I am writing a program which involves recursively making an instance of an object that may be passed as an argument. A sample of program:
from copy import copy
class test():
def __init__(self, sample=None):
if not sample:
self.a = int(input())
self.b = int(input())
else:
self = copy(sample)
# MAIN HERE..
sampleobj1 = test()
print (sampleobj1.a, sampleobj1.b)
sampleobj2 = test(sampleobj1)
print (sampleobj2.a, sampleobj2.b)
How do I clone an object (here sampleobj1) instead of manually assigning all variables of "sample" to self? I get the following error:
Traceback (most recent call last):
File "test.py", line 17, in <module>
print (sampleobj2.a, sampleobj2.b)
AttributeError: 'test' object has no attribute 'a'
Why doesn't the line: self = sample
work? Whatever I do, I always happen to get the same error. Individually copying the attributes seem just fine. But I am working on a code with a lot of attributes where copying each attribute seems a bit lengthy.
sampleobj3 = copy(sampleobj1)
also seems to work. But I want the copying to be done in the class & not in the main of the program.
The line self = sample
only overwrites a local variable, it does not replace the object initially stored in self
in memory.
To copy instances of a class, you have to fully define how to build a new object from an existing one.
You do this by defining the __copy__
and __deepcopy__
methods. These are the dunder methods used by copy.copy
and copy.deepcopy
respectively.
Furthermore, note that it is bad practice to have input
in your __init__
as it impedes the above solution. You should separate your logic and your IO.
import copy
class test():
def __init__(self, a, b):
self.a, self.b = a, b
def __copy__(self):
return type(self)(self.a, self.b)
# Here we encapsulate the IO part of your code
def test_factory():
a = int(input())
b = int(input())
return test(a, b)
foo = test_factory()
... # input the attributes
bar = copy.copy(foo) # a copy of your object