1

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.

toshiro92
  • 1,287
  • 5
  • 28
  • 42
  • 1
    Try using deepcopy function – Capie Sep 13 '20 at 10:34
  • Hi @Capie, indeed, I've tried and it worked perfectly! I let you answer to my question to mark it as resolved :-) Thank you! I've red a little bit about the difference between copy and deepcopy (here: https://www.python-course.eu/python3_deep_copy.php) and now it makes sense. – toshiro92 Sep 13 '20 at 14:06
  • Actually, the question has been marked as duplicate, but the "similar" article did not answered to my question, @Capie's answer did. – toshiro92 Sep 13 '20 at 14:10
  • 1
    Glad it helped. – Capie Sep 19 '20 at 15:51

0 Answers0