问题
When copy.copy or copy.deepcopy is called on an instance of a user-defined class that does not have a __copy__ or __deepcopy__ method, what does Python guarantee will happen? The official docs are disturbingly non-explicit on this matter. Will the function always just return a new instance of the same class with a shallow/deep copy of the original object's __dict__ (or whatever the equivalent is when __slots__ are involved)? Can the behavior differ between CPython, PyPy, etc.? Does the behavior differ between Python 2 and 3? (Ignore old-style classes.) What would make one need to define explicit __copy__/__deepcopy__ methods instead of using the default behavior?
References to explicit (better than implicit!) authoritative statements needed.
回答1:
From reading through the copy module's source, among other documents, I have determined the following:
When
copyordeepcopyis called on an instance of a user-defined new-style class that does not have a__copy__method and has not registered a callable with copy_reg.pickle, the instance's __reduce_ex__ method is called with a protocol of 2.objectdefines a__reduce_ex__method that is inherited by all new-style classes that do not define their own, and so every instance has a__reduce_ex__.__reduce_ex__ and __reduce__ return values usable for pickling, and the
copymodule uses these to emulate unpickling, creating & returning a new object made from the state of the original object. Moreover, when usingdeepcopy, the object's state (specifically, the third element of the tuple returned by__reduce_ex__/__reduce__) is deepcopied recursively before applying it to the new object.Some basic testing shows that calling
__reduce_ex__(2)on an instancexof a simple user-defined class returns(<function __newobj__>, (type(x),), x.__dict__, None, None). In both Python 2 and Python 3, if the class does not have a__setstate__method, thecopymodule will then perform the equivalent of the following:callable, args, state, _, _ = x.__reduce_ex__(2) y = callable(*args) if deepcopying: state = deepcopy(state) y.__dict__.update(state) return y
So it appears that the default behavior of the copy functions on instances of user-defined classes is indeed to do the useful & simple thing and create a new object with a (possibly deep) copy of the original object's state.
来源:https://stackoverflow.com/questions/33965606/default-behavior-of-copy-module-on-user-defined-classes