tags:

views:

827

answers:

5

Is there a library method to copy all the properties between two (already present) instances of the same class, in Python? I mean, something like Apache Commons' PropertyUtilsBean.copyProperties()

Thanks!

+3  A: 

If your class does not modify _ _ getitem _ _ or _ _ setitem _ _ for special attribute access all your attributes are stored in _ _ dict _ _ so you can do:

 nobj.__dict__ = oobj.__dict__.copy()    # just a shallow copy

If you use python properties you should look at inspect.getmembers() and filter out the ones you want to copy.

Peter Hoffmann
+3  A: 

Try destination.__dict__.update(source.__dict__).

Peter Hosey
+1  A: 

I know you down-modded copy, but I disagree. It's more clear to make another copy than to modify the existing in-place with dict manipulation, as others suggested (if you lose existing copy by reassigning the variable, it will get garbage-collected immediately). Python is not meant to be fast, it's meant to be readable (though I actually believe that copy() will be faster than the other methods).

J S
I agree, a copy is clearer, but the "use case" I'm working on requires in-place modification.. Thanks for your opinion though :)
Joril
A: 

At the risk of being modded down, is there a decent any use-case for this?

Unless we know exactly what it's for, we can't sensibly call it as "broken" as it seems.

Perhaps try this:

firstobject.an_attribute = secondobject.an_attribute
firstobject.another_attribute = secondobject.another_attribute

That's the sane way of copying things between instances.

Ali A
I know I can copy each property by hand, I was asking if there's a way to do it automatically :)As for the use case, I was trying to implement a refresh_from_persistence(obj) method that would update the object in-place, avoiding having to update every reference currently in memory.
Joril
Ah, I think I see. It's a nasty use case, since if you want a new object, use a new object (imo). I'll make a proper answer though ;)
Ali A
+1  A: 

If you have to do this, I guess the nicest way is to have a class attribute something like :

Class Copyable(object):
    copyable_attributes = ('an_attribute', 'another_attribute')

Then iterate them explicitly and use setattr(new, attr, getattr(old, attr)). I still believe it can be solved with a better design though, and don't recommend it.

Ali A