Sharing global data in Python

I am creating a project that requires data exchange on a global scale. I built a GlobalDataBase class to handle this data, which is similar to the method. How to avoid splitting class data between instances? and https://docs.python.org/2/tutorial/classes.html . However, I found something strange for 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 expected. But I could not understand why the first method does not work. Can someone explain the difference between the two methods?

+5
source share
1 answer

a assigned a list in the GlobalDataBase declaration. Each instance of GlobalDataBase begins with a link to the same list, let's call it an “original” list.

When you do self.a = value in the first example, you replace the link to the source list with the link to value , the list that you assigned for this instance or "I". Any newly created instance will still refer to the original list, and therefore gb2 displays an empty list - the original list, and not [1,2] - the new list.

Let's see how this works using id :

After declaring GlobalDataBase hold the link to a :

 id(GlobalDataBase.a) Out[112]: 290675912L #Original 

And the same link is stored in any instance that we create:

 gb1 = GlobalDataBase() id(gb1.a) Out[114]: 290675912L #Original 

and after copy_to_a you will see that it has changed:

 gb1.copy_to_a([1,2]) id(gb1.a) Out[116]: 290670536L #Changed! 

but gb2 still has the original link:

 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 add to the original list. As said, new instances refer to this list and “see” this change.

And here we see that the link 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 
+4
source

Source: https://habr.com/ru/post/1206023/


All Articles