“从以上代码中,我认为NewCounter1.count等于NewCounter1。class.count”
问题是,在您的问题中此句子出现时,仅在以下说明之后:
NewCounter1 = counter()NewCounter2 = counter()NewCounter2.__class__.count = 3
创建了 NewCounter1 和 NewCounter2
并修改了类属性 counter.count之后 ,
不存在对象 NewCounter1.count 和 NewCounter2.count ,因此 “等于” 没有实际意义。
。
请在之后查看 NewCounter1 的创建:
class counter: count = 0 def __init__(self): self.__class__.count += 1print 'counter.count BEFORE ==',counter.count # The result is 0NewCounter1 = counter()print 'nNewCounter1.__dict__ ==',NewCounter1.__dict__ # The result is {}print 'NewCounter1.count ==',NewCounter1.count # The result is 1print 'counter.count AFTER ==',counter.count # The result is 1NewCounter. _字典 _是实例的名称空间 NewCounter1
print NewCounter1.count打印一样
print counter.count
。然而,“计数”(字符串“数”)是不是在命名空间 NewCounter1 ,也就是说没有属性 数 在命名空间创建的实例!
这怎么可能 ?
这是因为没有assignement到“计数”标识内部创建实例的 _INIT _
- >有任何属性作为一个字段没有真正的创造 NewCounter1 ,也就是说没有创建实例属性。
结果是,在
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 equalsNewCounter1.__class__.count这意味着NewCounter1.count的VALUE即使该名确实不存在,也是类属性
NewCounter1 __的VALUE 。 .count 类 。这里的“是”是英语动词,不是该功能 是
测试两个对象的身份的语言,它的意思是“被认为具有”
当
NewCounter2.__class__.count = 3被执行时,只有类属性 counter.count 受到影响。
NewCounter1 和 NewCounter2 的命名空间保持为空,并 遵循 相同的机制来访问类以找到
counter.count 的值。
。
最后,当
NewCounter2.count = 5执行时,这一次将在INSTANCE属性 计数 中创建一个 NewCounter2
对象中的字段,并且“ count”出现在 NewCounter2 的命名空间中 。
它不会覆盖任何内容,因为实例中的内容之前
__dict__
没有任何内容。其他更改不会影响 NewCounter1 和 counter.count
以下代码更明确地显示了执行期间的基础事件:
from itertools import isliceclass counter: count = 0 def __init__(self): print (' | counter.count first == %d at %dn' ' | 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 %dn' ' | self.count second == %d at %dn' ' | 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 ('nn----- C1 = counter() ------------------------')C1 = counter()display('C1.__dict__',C1.__dict__, 'C1.count ',C1.count, 'ncounter.count ',counter.count)print ('nn----- 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 'nn------- C2.__class__.count = 3 ------------------------n'C2.__class__.count = 3display('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 'nn------- C2.count = 5 ------------------------n'C2.count = 5display('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) == 18735712C1.__dict__ == {} C1.count == 1 at 10021616counter.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 10021604C2.count == 2 at 10021604C1.__class__.count == 2 at 10021604C2.__class__.count == 2 at 10021604counter.count == 2 at 10021604------- C2.__class__.count = 3 ------------------------C1.__dict__ == {} C2.__dict__ == {} C1.count == 3 at 10021592C2.count == 3 at 10021592C1.__class__.count == 3 at 10021592C2.__class__.count == 3 at 10021592counter.count == 3 at 10021592------- C2.count = 5 ------------------------C1.__dict__ == {} C2.__dict__ == {'count': 5} C1.count == 3 at 10021592C2.count == 5 at 10021568C1.__class__.count == 3 at 10021592C2.__class__.count == 3 at 10021592counter.count == 3 at 10021592。
有趣的事情是
self.count = counter.count
在该行之前添加一条指令
self.__class__.count += 1 # <<=====
以观察结果的变化
。
综上所述,重点并不在乎,
__class__而是一种搜索属性的机制,而这种机制在被忽略时会产生误导。



