Best practice for copy method implementation
What's the best practice for implementing a method copy
in a class?
Here's an example of my class:
class MyClass:
def __init__(self, foo, bar=None):
self.foo = foo
if bar is not None:
self.bar = bar
else:
self.bar = {'Hello': 'Ciao'}
I found a post five years ago that suggests the following way:
import copy
def copy(self):
return MyClass(copy.copy(self.foo), copy.copy(self.bar))
Is this the only way to do it or are there other possibilities?
I need to create a copy of my object to avoid changing the function of the original object. The function looks something like this:
def translate_and_print(my_class, dict={'Hello':'Ciao'}):
temp = my_class # here I want to use the copy method: temp = my_class.copy()
temp.foo = temp.bar[temp.foo]
print(temp.foo)
Output of the following code: "Ciao", "Ciao", but should be "Ciao", "Hello"
mc = MyClass('Hello')
translate_and_print(mc)
print(mc.foo)
If I use the method copy()
, I have an error:
AttributeError: MyClass object has no attribute 'copy'
source to share
You have AttributeError
, I think that since you are just creating a method copy
, you need to create a method instead __copy__
.
import copy
class MyClass:
def __init__(self, name):
self.name = name
def __copy__(self):
return MyClass(self.name)
def __deepcopy__(self, memo):
return MyClass(copy.deepcopy(self.name, memo))
__copy__
for shallow copy and __deepcopy__
deep copy.
I hope you understand, Here is the link I follow
source to share
You should implement the method __copy__
and maybe also __deepcopy__
. The documentation states:
In order for a class to define its own copying implementation, it can define special methods
__copy__()
and__deepcopy__()
. The first is designed to perform shallow copy operation; no additional arguments are passed. The latter is called upon to perform a deep copy operation; it is passed one argument, a dictionary of notes. If an implementation__deepcopy__()
needs to make a deep copy of a component, it must call the functiondeepcopy()
with the component as the first argument and the annotation dictionary as the second argument.
With that said, unless you are doing any magic (like allocating C or calling in statefull C libraries) you won't need to implement it __copy__
yourself, but python provides this for you for free and you can just callcopy.copy(myobject)
source to share