2013-03-17 37 views
1

爲什麼即使在創建類的新實例之後,我仍然保持不變?爲什麼這個類在不同的實例中是相同的?

class Test(object): 
    i = 0 
    def add(self): 
     Test.i += 1 

運行這段代碼

t = Test() 
print t.i 
t.add() 
t2 = Test() 
print t2.i 
print t.i 

,帶出

0 
1 
1 

爲什麼不能同時t.i和t2.i等於0?它們不應該等於0,因爲行t2 = Test()會將i重置爲0?

+2

這是一個*類變量*,正如你正確地說自己 - 它屬於類,而不是這個類的特定實例。 – Niko 2013-03-17 22:12:26

+0

請注意我的回答 – eyquem 2013-03-17 23:01:56

回答

2

i是一個類變量,而不是一個實例變量。它受到課程本身的約束(這就是爲什麼你可以編寫Test.i,即使沒有Test的實例存在)。

你必須做i一個實例變量:

class Test(object): 
    def __init__(self): 
     self.i = 0 

    def add(self): 
     self.i += 1 
+0

我明白了,但是當「t2 = Test()」運行時,是否再次運行「i = 0」行並重置i = 0? – bab 2013-03-17 22:33:47

+1

@student:不。你的班級定義了一次。每次初始化類的新實例時,都會運行'__init__'內部的東西。 – Blender 2013-03-17 22:34:20

+1

你爲什麼期望這條線再次運行? **類**僅創建一次(否則,這將是非常無用的,因爲實例將屬於不同的類!)。 – 2013-03-17 23:15:14

1

要修改,而不是實例的屬性,整個類的屬性。嘗試:

class Test(object): 
    i = 0 
    def add(self): 
     self.i += 1 

的Python自動將實例作爲自變量self給方法。在該方法中,您可以將實例的屬性稱爲self.i

0
class Test(object): 
    i = 0 
    def add(self): 
     Test.i += 1 

print "Test.i == ",Test.i 
print "'i' in dir(Test) == ",'i' in dir(Test) 
print "'i' in Test.__dict__ == ",'i' in Test.__dict__ 

t1 = Test() 
print '\n# t1 = Test() executed' 
print "t1.i == ",t1.i 
print "'i' in dir(t1) == ",'i' in dir(t1) 
print "'i' in t1.__dict__ == ",'i' in t1.__dict__ 

結果

Test.i == 0 
'i' in dir(Test) == True 
'i' in Test.__dict__ == True 

# t1 = Test() executed 
t1.i == 0 
'i' in dir(t1) == True 
'i' in t1.__dict__ == False 

對象的名稱__dict__的屬性是表示該對象的命名空間的字典,也就是說它所包含的對象的屬性。

同時,我們有:

目錄([對象])

如果對象有一個名爲__dir__()方法,這個方法會被稱爲 並且必須返回屬性的列表。

那麼,怎麼可能是dir(t1)包含屬性t1.__dict__不? 儘管所有兩個dir(Test)Test.__dict__都包含屬性i

這是爲回答您的問題同樣的原因:

返回一個對象的屬性的行爲是尷尬。
`dir(object)反映了這種尷尬:

默認目錄()機制與不同類型的對象 不同的行爲,因爲它試圖產生最相關的,而不是 完整,信息:

•如果對象是模塊對象,則該列表將包含模塊屬性的名稱 。
•如果對象是類型或類對象,則 列表將包含其屬性的名稱,並遞歸地包含其基礎的 屬性。
•否則,列表中包含對象的 屬性名稱中其類的屬性的名字,和 遞歸的它的類的基類的屬性。

然後,回答你的問題有兩個部分:

1)dir(t1)給出什麼被視爲對象,但對象的真實名稱空間的屬性,暴露t1.__dict__不包含屬性這是因爲它已經被回答了,實際上是一個班級的屬性。

因此,僞屬性兩個實例T1T2出現等於因爲表達t1.it2.i實際上評爲Test.i
以同樣的方式,dir(t1)dir(t2)包括類的屬性Test.i

2)如何將表達式t1.i評估爲Test.i
正因爲如此(這構成了我的答案的其他信息):

一個類的實例有一個用字典是 在屬性引用首位被搜索實現的名字空間。當在那裏找不到 屬性,並且該實例的類具有該名稱的 屬性時,搜索將繼續使用類 屬性。

http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy

這意味着,當一個對象的命名空間中找不到一個屬性,就搜索,其對象是實例的類的命名空間。

相關問題