Can I efficiently swap two class instances by swapping __dict__?

后端 未结 4 1178
别那么骄傲
别那么骄傲 2021-01-08 00:03

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

4条回答
  •  离开以前
    2021-01-08 00:44

    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.

提交回复
热议问题