问题
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
copy
ordeepcopy
is 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.object
defines 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
copy
module 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 instancex
of 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, thecopy
module 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