我正在阅读 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 有什么区别,为什么会导致递归错误?
在
def __getitem__(self, key): return self[key]
self[key]``__getitem__调用调用self[key]…无限递归的最低级别。
self[key]``__getitem__
self[key]
在:
def get(self, key): return self[key]
self[key]也调用最低级别__getitem__,但从dict类中调用,因此它不会递归:它可以工作(您只是重载了get方法,仅此而已)
__getitem__
dict
get
那是因为self[key]inMyDict2.__getitem__(key)等价于(即调用)self.__getitem__(key)=> 无限递归。
MyDict2.__getitem__(key)
self.__getitem__(key)