2010-02-19 58 views
1

對於類A,爲什麼在對象和對象b之間共享一個成員變量映射?爲什麼在對象之間共享python關聯映射成員變量

>>> class A: 
...  aMap = {} 

>>> a = A() 
>>> a.aMap["hello"] = 1 

>>> b = A() 
>>> b.aMap["world"] = 2 

>>> c = [] 
>>> c.append(a) 
>>> c.append(b) 

>>> for i in c: 
...  for j in i.aMap.items(): 
...   print j 
('world', 2) 
('hello', 1) 
('world', 2) 
('hello', 1) 
+0

我相信http://stackoverflow.com/questions/1132941/least-astonishment- in-python-the-mutable-default-argument解釋了這一點。 – aem 2010-02-19 21:47:53

+0

[我如何避免在實例間共享Python類數據?](http://stackoverflow.com/questions/1680528/how-do-i-avoid-having-python-class-data-shared-among - 物質) – 2013-02-23 15:41:45

回答

5

因爲您將其定義爲類屬性,而不是實例屬性。

如果希望它作爲實例屬性,而不是實例之間共享,則必須定義它是這樣的:

class A(object): 
    def __init__(self): 
     self.aMap = {} 
+0

+1:類屬性在對象之間共享。小心諸如「成員變量」之類的模糊詞組。嘗試談論「實例屬性」和「類屬性」,而不是「成員變量」,這是模糊的。 – 2010-02-19 21:48:37

+2

總是繼承'object'。 – 2010-02-19 21:49:54

+0

確實如此,尤其是因爲它是使用屬性的唯一方式,所以在將來需要它們時:-) – gruszczy 2010-02-19 21:50:50

3

由於其類屬性,而不是對實例屬性(「成員變量」 )。

要使其成爲實例屬性,請將其指定給實例,例如,在構造函數中:

class A: 
    def __init__(self): 
     self.aMap = {} 

但你也可以這樣做:

a = A() 
a.aMap = {} 
+2

始終繼承'object'。 – 2010-02-19 21:50:29

0

因爲你有效地定義一個class variable而不是instance variable

要定義一個實例變量,你應該這樣做的一個方法指對象本身(一般self):

class A(object): 
    class_variable = 0 

    def __init__(self, a, b): 
     self.instance_variable = a 
     class_variable = b 

>>> a=A(1,2) 
>>> print a.instance_variable 
1 
>>> print a.class_variable 
2 
>>> b=A(2,1) 
>>> print b.instance_variable 
2 
>>> print b.class_variable 
1 
>>> print a.instance_variable 
1 
>>> print a.class_variable 
1