我一直在研究super()
是如何工作的。我遇到了演示如何创建有序计数器的this recipe:
from collections import Counter, OrderedDict
class OrderedCounter(Counter, OrderedDict):
'Counter that remembers the order elements are first seen'
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__,
OrderedDict(self))
def __reduce__(self):
return self.__class__, (OrderedDict(self),)
例如:
oc = OrderedCounter('adddddbracadabra')
print(oc)
OrderedCounter(OrderedDict([('a', 5), ('d', 6), ('b', 2), ('r', 2), ('c', 1)]))
有人能解释这是怎么神奇地工作的吗?
这也出现在Python documentation中。
OrderedCounter是OrderedDict documentation中的一个示例,不需要重写任何方法即可工作:
调用类方法时,Python必须找到要执行的正确方法。它搜索类层次结构时有一个定义的顺序,称为“方法解析顺序”或mro。mro存储在属性
__mro__
:当OrderedDict的一个实例调用
__setitem__()
时,它将按以下顺序搜索类:OrderedCounter
、Counter
、OrderedDict
(找到它的位置)。所以像oc['a'] = 0
这样的语句最终会调用OrderedDict.__setitem__()
。相反,mro中的任何子类都不会重写
__getitem__
,因此count = oc['a']
由dict.__getitem__()
处理。对于像
oc.update('foobar').
First这样的语句,会出现一个更有趣的调用序列,Counter.update()
被调用。Counter.update()
的代码使用self[elem],它被转换为对OrderedDict.__setitem__()
的调用。的代码调用dict.__setitem__()
。如果基类被反转,它将不再工作。因为mro是不同的,调用错误的方法。
有关mro的更多信息可以在Python 2.3documentation中找到。
相关问题 更多 >
编程相关推荐