以下代码不会引发KeyError。
from collections import defaultdict
class A(defaultdict):
def __init__(self):
self.default_factory = int
a = A()
print(a[42]) # out: 0
以下代码引发了KeyError。
from collections import defaultdict
class A(defaultdict):
def __init__(self):
pass
class B(A):
default_factory = int
b = B()
print(a[42]) # out: KeyError: 42
在我有缺陷的想象中,第二个例子就像这样:
1)在构建A
对象时调用父__init__
类的b
方法
2)参考不存在的密钥defaultdict
__missing__
班级的42
方法
3)仅参考b
对象的default_factory
属性才能找到此类属性
4)参考B
班级的属性,找到定义为default_factory
的{{1}}
5)将int
返回int
班级defaultdict
方法
6)致电__missing__
(default_factory
),默认返回int
0
7)将__missing__
对象的键b
值定义为42
8)打印0
也许我对第2步有误?我的哪些假设是不正确的,或者我的第一个和第二个例子之间的关键区别是什么?
答案 0 :(得分:1)
defaultdict
不是Python类,它是 C类型。因此,它不支持对类进行属性查找,它只支持在实例上设置default_factory
。
换句话说,第4步永远不会发生。
第2步发生,但此步骤在C中实现为使用:
PyObject *factory = dd->default_factory;
和default_factory
仅定义为实例的成员。请参阅defaultdict
C source。