我正在阅读Fluent Python,并试图更深入地了解字典。
因此,当我运行以下内容时,结果很容易理解,get()和dunder getitem()都返回相同的结果
sample = {'a':1, 'b':2}
print(sample.__getitem__('a')) # 1
print(sample.get('a')) # 1
当我用get()子类化dict时,我得到了一个工作实例
class MyDict(dict):
def __missing__(self, key):
return 0
def get(self, key):
return self[key]
d = MyDict(sample)
print(d['a']) # 1
print(d['c']) # 0
现在,如果我用dunder getitem()替换get(),我会收到一个错误,我不确定为什么。
class MyDict2(dict):
def __missing__(self, key):
return 0
def __getitem__(self, key):
return self[key]
d = MyDict2(sample)
print(d['a'])
print(d['c'])
错误
RecursionError: maximum recursion depth exceeded while calling a Python object
所以问题是,在这种情况下get和dunder getitem有什么区别?为什么会导致递归错误?
答案 0 :(得分:6)
在
def __getitem__(self, key):
return self[key]
self[key]
调用最低级__getitem__
,调用self[key]
...无限递归。
在:
def get(self, key):
return self[key]
self[key]
也会调用最低级__getitem__
,但是来自dict
类,所以它不会递归:它可以工作(你只是重载了get
方法,那就是全部)
答案 1 :(得分:3)
这是因为self[key]
中的MyDict2.__getitem__(key)
等同于(即来电)self.__getitem__(key)
=>无限递归。