I am building a project that requires the data to be shared globally. I built a class GlobalDataBase to handle these data, which is like the way in How do I avoid having class data shared among instances? and https://docs.python.org/2/tutorial/classes.html . However, I found something a little bit weird to me. My code is as follows:
class GlobalDataBase:
a = []
def copy_to_a(self, value):
self.a = value
def assign_to_a(self, value):
for idx in range(0, len(value)):
self.a.append(value[idx])
def test_copy():
gb1 = GlobalDataBase()
gb1.copy_to_a([1,2])
print gb1.a
gb2 = GlobalDataBase()
print gb2.a
def test_assign():
gb1 = GlobalDataBase()
gb1.assign_to_a([1,2])
print gb1.a
gb2 = GlobalDataBase()
print gb2.a
The output of test_copy
is
[1,2]
[]
The output of test_assign
is
[1,2]
[1,2]
The result of the second method is what I was expecting. But I could not understand why the first method doesn't work. Could anyone explain the difference between these two methods?
a
is assigned with a list on GlobalDataBase
's declaration. Each instance of GlobalDataBase
starts out with a reference to that same list, let's term it the "original" list.
When you do self.a = value
in your first example, you replace, for that instance or "self", the reference to the original list with a reference to value
, the list you assigned. Any new instance created will still reference the original list, and that's why gb2
prints out an empty list - the original list, and not [1,2]
- the new list.
Let's see how that works, using id:
Once declared, GlobalDataBase
hold a reference to a
:
id(GlobalDataBase.a)
Out[112]: 290675912L #Original
And that same reference is held by any instance we create:
gb1 = GlobalDataBase()
id(gb1.a)
Out[114]: 290675912L #Original
and after copy_to_a
, you can see that it changed:
gb1.copy_to_a([1,2])
id(gb1.a)
Out[116]: 290670536L #Changed!
but gb2
still has the original reference:
id(gb2.a)
Out[118]: 290675912L #Original
You said you understood the second example, but for completeness, when you do self.a.append(value[idx])
you append to the original list. As said, new instances have a reference to that list, and "see" that change.
And here we can see the reference does not change:
gb1 = GlobalDataBase()
id(gb1.a)
Out[120]: 290675912L #Original
gb1.assign_to_a([1,2])
id(gb1.a)
Out[122]: 290675912L #Original
gb2 = GlobalDataBase()
id(gb2.a)
Out[124]: 290675912L #Original
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With