I have a very strange behavior regarding the copy function of Python's object. I've reproduced in a simpler way my code as below:
import copy,string,random
class Art:
def __init__(self,title,hashes=[]):
self.title = title
self.hashes = hashes
def addHash(self,hash):
self.hashes.append(hash)
def get_random_string(length):
letters = string.ascii_lowercase
result_str = ''.join(random.choice(letters) for i in range(length))
return result_str
def main():
arts = [Art("my first object"),Art("my second object"),Art("my third object"),Art("my fourth object")]
for art in arts:
artC = copy.copy(art)
print("{} - {}".format(artC.title,artC.hashes))
artC.addHash(get_random_string(8))
artC.addHash(get_random_string(8))
if __name__ == "__main__":
main()
However, when I execute the program, the hashes are still present, and accumulate themselves, even if it should have been overwritten by artC = copy.copy(art)
, and even if they are actually different objects. I have the following result:
my first object- []
my second object- ['qdfnaiwh', 'olwnuvtk']
my third object- ['qdfnaiwh', 'olwnuvtk', 'kirvwdgj', 'arypneum']
my fourth object- ['qdfnaiwh', 'olwnuvtk', 'kirvwdgj', 'arypneum', 'abscxtmp', 'qkwjiddw']
And when I add at the end of the loop the following:
del artC
try:
print(artC.title)
except Exception as e:
print(e)
I still have the same behavior, even if artC has been deleted:
my first title - []
local variable 'artC' referenced before assignment
my second title - ['qqbmpymh', 'axzkvura']
local variable 'artC' referenced before assignment
my third title - ['qqbmpymh', 'axzkvura', 'xubohbta', 'ckyrohsr']
local variable 'artC' referenced before assignment
my fourth title - ['qqbmpymh', 'axzkvura', 'xubohbta', 'ckyrohsr', 'awnkfvld', 'vpubxhjv']
local variable 'artC' referenced before assignment
Did I uncorectly used the del function? Why there is still something inside an object that does not exist anymore, and should not be present in different objects? I'm using the Python 3.5.2
version if that can help.
Thank you in advance.
SOLUTION
As the question has been marked as duplicate and is now closed, I will answer to my own question below (Thanks @Capie for the hint):
The solution is to use deepcopy
instead of copy
. The reason behind this is that when copy
is used, it copies only the reference of the same list, and do not recreate a new one for the new object.
So object1 and object2 will share the same list, instead of having their own one, which explains the behavior above.
You can also have more details thanks to this interesting article.