'Why class instances still share same memory of deep copied list inside?
I declared these variables as class context. Just delete the declaration outside the function.
I have a class. In its __init__ function, I created a list like this:
self.__test_list = deepcopy([])
Then I append about 50 objects(instances), after using this list, I create new instance of this class. Also append about 50 objects. And the two instance shared this self.__test_list! Then I tried deepcopy() this list when every append, delete instance when used and call gc.collect() even deepcopy() the whole instance. But it is not working at all.
I'm using Python 3.10 with anaconda.
Minimal example:
import random
from copy import deepcopy
import gc
class A:
__some_var = 0
def __init__(self):
self.__some_var = random.randint(0, 65535)
class Test:
__test_list = deepcopy([])
def __init__(self):
super().__init__()
for i in range(50):
self.__test_list.append(A())
self.__test_list = deepcopy(self.__test_list)
print(len(self.__test_list))
if __name__ == "__main__":
gc.enable()
for g in range(1, 2):
for t in range(1, 6):
test = Test()
del test
gc.collect()
It is expected to print:
50
50
50
50
50
50
But it print out:
50
100
150
200
250
__ prefix does not influence because after I remove this prefix it still behaves like that.

Solution 1:[1]
You first mention this line: self.__test_list = deepcopy([]).
Nowhere in the subsequent code do you include that line.
You do have the line: __test_list = deepcopy([]) which creates a class variable of that name.
However, I suspect that the deepcopy([]) is not doing what you think its doing. What that is doing is to take the literal list [] and pass that to the deepcopy function which makes a deep copy of it and returns it. But the literal list [] is thrown away and you end up with another empty list.
This is what I suspect you want:
import random
class A:
__some_var = 0
def __init__(self):
self.__some_var = random.randint(0, 65535)
class Test:
def __init__(self):
self.__test_list = []
for i in range(50):
self.__test_list.append(A())
print(len(self.__test_list))
if __name__ == "__main__":
for g in range(1, 2):
for t in range(1, 6):
test = Test()
del test
Output as requested.
What the above code does is to create an instance level list for each Test created. Each list is populated with a number of instances of the A class and it prints the length of the list.
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 | quamrana |
