Reputation: 157
I broke down my problem to the following example program
xy8_block = [
{'pulse': {}},
]
class Dummy:
def __init__(self, block=list(xy8_block)):
self._block = block
dumdum = Dummy()
dumdum._block[0]['pulse']['test'] = 0
print(xy8_block)
If I run the program, the variable xy8_block
is changed, although both variables dumdum._block
and
xy8_block
have both a different memory address.
How can I avoid this problem without directly initialising the class with the value.
Thanks in advance.
Upvotes: 3
Views: 143
Reputation: 5948
Instead of:
def __init__(self, block=list(xy8_block)):
Do:
from copy import deepcopy
def __init__(self, block=deepcopy(xy8_block)):
When you do list(my_list)
, you do a shallow copy of your list, which means its elements are still copied by reference.
In other words, as you correctly mentioned, xy8_block
and dumdum._block
do have different memory addresses. However, if you check memory addresses for xy8_block[0]
and dumdum._block[0]
, you will see that they are the same.
By using deepcopy
, you copy the list and its elements' values, not their references.
EDIT
As wisely noted by @FMc, this will still make all instances' _block
attributes to point to the same object, since the list that results from deepcopy
is created in the method's definition, not in its execution. So here's my suggestion:
from copy import deepcopy
class Dummy:
def __init__(self, block=None):
self._block = block or deepcopy(xy8_block)
Upvotes: 4
Reputation: 42411
Get a fresh block each time:
def new_xy8_block():
return [{'pulse': {}}]
class Dummy:
def __init__(self, block=None):
self._block = block or new_xy8_block()
ds = [Dummy() for _ in range(5)]
ds[0]._block[0]['pulse']['test'] = 0
for d in ds:
print d._block
Upvotes: 2