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'
答案 0 :(得分:6)
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)
答案 1 :(得分:3)
您有一个AttributeError
,我认为这是因为您只是创建了一个copy
方法,而不是您需要创建__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__
浅层复制方法和__deepcopy__
深层复制方法。
我希望你明白这一点,Here is the link i follow
答案 2 :(得分:1)
以下实现仅复制而无需调用init()方法。
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