I have a big class with lots of members, and quite a few references to instances of this class lying around. Unfortunately (for reasonable reasons) all these references are the wrong way around.
Instead of re-creating each (and finding and updating everywhere the objects are referenced), or adding an extra level of indirection each time I access this class, or individually swapping members, I have defined a method:
def swap(self, other):
assert(isinstance(other, self.__class__))
self.__dict__, other.__dict__ = other.__dict__, self.__dict__
so I can do:
instance_a.swap(instance_b)
# now all references to instance_a everywhere are as if instance_a is instance_b
The question:
It seems to work fine (I don't use __slots__
), but it feels like there might be a reason I shouldn't do this, is there?
Here's my actual use case:
I have a type that implements comparison operators in a (necessarily) expensive way. I have various sorted data-structures containing objects of this type.
When I do something to one of the objects, I know that the comparison order has changed, and that order in my data structures (all of them!) can be restored by swapping the modified object with the 'next bigger' one.
Python stores results on a stack. For swapping variables, it can load them on the stack, swap the order of the top two variables, and then store them back, now in opposite order.
What you're doing is possible, although it will make people cringe because it is hackish. If at all possible, I would suggest that you look at rewriting/refactoring your comparison operators. That will give you the best outcome by far. Of course, not knowing the scope or time-frame involved, it is very difficult to tell whether this is immediately practical, but trust me, you will spend less time re-writing in the long term if you can do things "right".
Realistically, it sounds like you're dealing with three classes -- a data object and two utility classes -- but that is another issue.
This will break, so I am going to go ahead and say, "no, you cannot swap classes by swapping __dict__
s":
>>> class Foo:
... def __init__(self):
... self.__bar = 1
... def printBar(self):
... print self.__bar
...
>>> class Bar:
... def __init__(self):
... self.__bar=2
... def printBar(self):
... print self.__bar
...
>>> f=Foo()
>>> f.printBar() # works as expected
1
>>> f=Foo()
>>> b=Bar()
>>> f.__dict__, b.__dict__ = b.__dict__, f.__dict__
>>> f.printBar() # attempts to access private value from another class
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in printBar
AttributeError: Foo instance has no attribute '_Foo__bar'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With