'Best practice to implement copy method in a class?
What is the best practice to implement the copy method in a class?
Here is 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 of five years ago that suggests the following way:
import copy
def copy(self):
return MyClass(copy.copy(self.foo), copy.copy(self.bar))
Is it still the only way to do it or are there other possibilities?
I need to create a copy of my object to avoid that a function changes the original object. The function is 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)
The output of the following code is "Ciao", "Ciao" but should be "Ciao", "Hello"
mc = MyClass('Hello')
translate_and_print(mc)
print(mc.foo)
If I use the copy() method I have the error:
AttributeError: 'MyClass' object has no attribute 'copy'
Solution 1:[1]
You got an AttributeError, I think that's because you just create a copy method, instead of that you need to create __copy__ method.
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__ method for shallow copy and __deepcopy__ for deep copy.
I hope you got the point, Here is the link i follow
Solution 2:[2]
You should implement the __copy__ method, and possibly also __deepcopy__. The documentation states:
In order for a class to define its own copy implementation, it can define special methods
__copy__()and__deepcopy__(). The former is called to implement the shallow copy operation; no additional arguments are passed. The latter is called to implement the deep copy operation; it is passed one argument, the memo dictionary. If the__deepcopy__()implementation needs to make a deep copy of a component, it should call thedeepcopy()function with the component as first argument and the memo dictionary as second argument.
With that said, unless you do some magic (e.g. C allocations, or calls to statefull C libraries), you should not need to implement __copy__ yourself, but python provides this for you for free, and you can simply call copy.copy(myobject)
Solution 3:[3]
Follow implementation makes just copy, without calling the init() method.
class MyClass(BaseClass):
def __init__(self, name):
super().__init__()
self.name = name
def __copy__(self):
obj = type(self).__new__(self.__class__)
obj.__dict__.update(self.__dict__)
return obj
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Arun V Jose |
| Solution 2 | |
| Solution 3 | RedEyed |
