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
If I understand correctly, you are actually swapping instances of a class, not classes.
Instance state is kept in two possible places: __slots__
and __dict__
. If you swap those, you've basically swapped instances while retaining the original name bindings. One caveat is that the class cannot be immutable (must not define __hash__()
) as any instances that were already members of a set or keys in a dictionary would then become irretrievable.
If it were me, I think I would have the .swap() method be a class method instead -- I think it would read easier:
class SomeBigClass():
@staticmethod
def swap_dict(instance_a, instance_b):
instance_a.__dict__, instance_b.__dict__ = \
instance_b.__dict__, instance_a.__dict__
@classmethod
def swap_slot(cls, instance_a, instance_b):
values = []
for attr in cls.__slots__:
values.append(
(attr,
getattr(instance_a, attr),
getattr(instance_b, attr),
))
for attr, val1, val2 in values:
setattr(instance_a, attr, val2)
setattr(instance_b, attr, val1)
and then later
SomeBigClass.swap_dict(this_instance, other_instance)
or
SomeBigClass.swap_slot(this_instance, other_instance)
Why shouldn't you do this? If you have instances bound to names you should not do this. Consider:
frubbah = SomeBigClass(attr="Hi, Mom!")
zikroid = SomeBigClass(attr='Hi, Dad!")
SomeBigClass.swap_dict(frubbah, zikroid)
After the swap, potentially everything you thought you knew about zikroid has changed.