copy.copy uses copy if defined; otherwise falls back to default shallow copy
copy.copy() produces a shallow copy of an object. When the object's class defines copy, copy.copy calls that method and uses its return value as the copy. If copy is not defined, copy.copy falls back to the default behavior: for most objects, it creates a new instance and copies the dict (shallowly). For objects with slots or custom reduce_ex, the default may differ. Defining copy lets you control exactly what is copied, which is useful when the object holds resources, caches, or references that should not be duplicated. The risk is that a poorly implemented copy can break expectations, for example by returning self or by not copying mutable state. Always ensure copy returns a new object of the same type with the desired shallow-copy semantics.
With copy: copy.copy calls obj.copy() and returns its result.
Without copy: copy.copy uses the default shallow copy, typically copying dict.
Shallow copy means nested objects are shared, not duplicated.
Define copy when you need to control which attributes are copied or to reset caches.
Define deepcopy for deep copies, which otherwise uses pickle-like recursion.
Common mistake: returning self from copy, which does not create a copy.
Common mistake: forgetting to copy mutable attributes in copy, leading to shared state.
Version note: the copy module and copy protocol have been stable since Python 2.
0-2 years experience
2-5 years experience
5-8 years experience
8+ years experience