「從上面的代碼,我想,也許NewCounter1.count等於NewCounter1 _class_.count。」
的問題是,這句話在你的問題的那一刻,唯一的指令後:
NewCounter1 = counter()
NewCounter2 = counter()
NewCounter2.__class__.count = 3
具有創建NewCounter1和NewCounter2
和具有MODI田間類屬性counter.count,
有存在沒有對象NewCounter1.count也不NewCounter2.count,然後「等於」沒有實際意義。
。
見NewCounter1,只是以後的創作:
class counter:
count = 0
def __init__(self):
self.__class__.count += 1
print 'counter.count BEFORE ==',counter.count # The result is 0
NewCounter1 = counter()
print '\nNewCounter1.__dict__ ==',NewCounter1.__dict__ # The result is {}
print 'NewCounter1.count ==',NewCounter1.count # The result is 1
print 'counter.count AFTER ==',counter.count # The result is 1
NewCounter._ 字典 _是實例的名稱空間NewCounter1
print NewCounter1.count
版畫一樣print counter.count
但是,'count'(字符串'count')不在名稱空間NewCounter1,也就是說在創建的實例的名稱空間中沒有屬性count!
這怎麼可能?
這是因爲實例不assignement創建一個「計數」標識內_ 初始化 _
- >存在NewCounter1沒有真正的創造任何屬性作爲一個字段,即說不創建INSTANCE屬性。
的結果是,當指令
print 'NewCounter1.count ==',NewCounter1.count
評估,解釋沒有找到在NewCounter1的命名空間的實例屬性,然後進入該類的實例來搜索在這個類的名字空間中鍵入'count';在那裏它發現「count」作爲CLASS屬性的關鍵字,並且可以將對象counter.count的VALUE作爲VALUE顯示以響應該指令。
一個類實例有一個實現爲字典的名稱空間,它是 第一個在其中搜索屬性引用的地方。當在那裏找不到 屬性,並且該實例的類具有該名稱的 屬性時,搜索將繼續使用類 屬性。 http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy
所以,NewCounter1.count equals NewCounter1.__class__.count
這裏意味着NewCounter1.count的價值,即使這一個實際上並不存在,是類屬性NewCounter1的值。 類.count。這裏的「被」是英文動詞,而不是功能的是,測試兩個對象的身份的語言,這意味着「被認爲具有」
當執行NewCounter2.__class__.count = 3
,只有類屬性計數器.count受影響。 NewCounter1和NewCounter2的命名空間保持爲空,並且類似地找到counter.count的值。
。
在結束時,當執行NewCounter2.count = 5
,此時實例屬性計數作爲在NewCounter2對象的字段創建和「計數」出現在NewCounter2的命名空間。
它沒有覆蓋任何東西,因爲沒有任何的實例的__dict__
沒有其他變化之前影響NewCounter1和counter.count
下面的代碼執行過程中顯示更明確的基本事件:
from itertools import islice
class counter:
count = 0
def __init__(self):
print (' | counter.count first == %d at %d\n'
' | self.count first == %d at %d')\
% (counter.count,id(counter.count),
self.count,id(self.count))
self.__class__.count += 1 # <<=====
print (' | counter.count second == %d at %d\n'
' | self.count second == %d at %d\n'
' | id(counter) == %d id(self) == %d')\
% (counter.count,id(counter.count),
self.count,id(self.count),
id(counter),id(self))
def display(*li):
it = iter(li)
for ch in it:
nn = (len(ch)-len(ch.lstrip('\n')))*'\n'
x = it.next()
print '%s == %s %s' % (ch,x,'' if '__dict__' in ch else 'at '+str(id(x)))
display('counter.count AT START',counter.count)
print ('\n\n----- C1 = counter() ------------------------')
C1 = counter()
display('C1.__dict__',C1.__dict__,
'C1.count ',C1.count,
'\ncounter.count ',counter.count)
print ('\n\n----- C2 = counter() ------------------------')
C2 = counter()
print (' -------------------------------------------')
display('C1.__dict__',C1.__dict__,
'C2.__dict__',C2.__dict__,
'C1.count ',C1.count,
'C2.count ',C2.count,
'C1.__class__.count',C1.__class__.count,
'C2.__class__.count',C2.__class__.count,
'\ncounter.count ',counter.count)
print '\n\n------- C2.__class__.count = 3 ------------------------\n'
C2.__class__.count = 3
display('C1.__dict__',C1.__dict__,
'C2.__dict__',C2.__dict__,
'C1.count ',C1.count,
'C2.count ',C2.count,
'C1.__class__.count',C1.__class__.count,
'C2.__class__.count',C2.__class__.count,
'\ncounter.count ',counter.count)
print '\n\n------- C2.count = 5 ------------------------\n'
C2.count = 5
display('C1.__dict__',C1.__dict__,
'C2.__dict__',C2.__dict__,
'C1.count ',C1.count,
'C2.count ',C2.count,
'C1.__class__.count',C1.__class__.count,
'C2.__class__.count',C2.__class__.count,
'\ncounter.count ',counter.count)
結果
counter.count AT START == 0 at 10021628
----- C1 = counter() ------------------------
| counter.count first == 0 at 10021628
| self.count first == 0 at 10021628
| counter.count second == 1 at 10021616
| self.count second == 1 at 10021616
| id(counter) == 11211248 id(self) == 18735712
C1.__dict__ == {}
C1.count == 1 at 10021616
counter.count == 1 at 10021616
----- C2 = counter() ------------------------
| counter.count first == 1 at 10021616
| self.count first == 1 at 10021616
| counter.count second == 2 at 10021604
| self.count second == 2 at 10021604
| id(counter) == 11211248 id(self) == 18736032
-------------------------------------------
C1.__dict__ == {}
C2.__dict__ == {}
C1.count == 2 at 10021604
C2.count == 2 at 10021604
C1.__class__.count == 2 at 10021604
C2.__class__.count == 2 at 10021604
counter.count == 2 at 10021604
------- C2.__class__.count = 3 ------------------------
C1.__dict__ == {}
C2.__dict__ == {}
C1.count == 3 at 10021592
C2.count == 3 at 10021592
C1.__class__.count == 3 at 10021592
C2.__class__.count == 3 at 10021592
counter.count == 3 at 10021592
------- C2.count = 5 ------------------------
C1.__dict__ == {}
C2.__dict__ == {'count': 5}
C1.count == 3 at 10021592
C2.count == 5 at 10021568
C1.__class__.count == 3 at 10021592
C2.__class__.count == 3 at 10021592
counter.count == 3 at 10021592
。
一個有趣的事情是增加一個指令
self.count = counter.count
前行
self.__class__.count += 1 # <<=====
觀察結果
的變化。
總之,這個問題並不是關於__class__
,而是關於搜索一個屬性的機制,而這種機制在被忽略時會產生誤導。
對於冗長的問題+1。 –
另外,'是'不會做你認爲它在這裏做的事情,特別是關於小整數。 –