python中__missing__方法与collections.UserDict类导致的递归理解
如下是我执行的代码和报错:
# class UserDict(_collections_abc.MutableMapping): # def __getitem__(self, key): # if key in self.data: # return self.data[key] # if hasattr(self.__class__, "__missing__"): # return self.__class__.__missing__(self, key) # raise KeyError(key) class UserDictSub(UserDict): def __missing__(self, key): return self[_upper(key)] ud = UserDictSub(A='letter A') print(ud['V']) File "D:\geek growing\Languages\FluentPython2\3. Dictionaries and Sets\missing.py", line 27, in __missing__ return self[_upper(key)] File "E:\Anaconda\installation\envs\FluentPython2Env\lib\collections\__init__.py", line 1105, in __getitem__ return self.__class__.__missing__(self, key) File "D:\geek growing\Languages\FluentPython2\3. Dictionaries and Sets\missing.py", line 27, in __missing__ return self[_upper(key)] File "D:\geek growing\Languages\FluentPython2\3. Dictionaries and Sets\missing.py", line 7, in _upper return x.upper() RecursionError: maximum recursion depth exceeded while calling a Python object
关于这个递归报错的理解:
代码的执行流程:
ud['V']的调用触发了__getitem__方法,因为在UserDictSub类中没有直接定义__getitem__方法,所以从父类UserDict继承的__getitem__方法被调用。- 在
__getitem__方法中,检查键'V'是否在self.data中,这里self.data是{'A': 'letter A'}。因为'V'不在self.data中,所以继续执行下面的代码。 - 在
__getitem__方法中,检查是否定义了__missing__方法。由于在UserDictSub中定义了__missing__方法,所以执行self.__class__.__missing__(self, key)。 - 在
__missing__方法中,执行self[_upper(key)]。此时key是'V'。 - 调用
_upper('V'),这将执行return self['V'.upper()]。 - 回到步骤1,递归调用
__getitem__方法,继续执行之前的步骤,直到达到 Python 解释器的最大递归深度,抛出RecursionError。
这就是递归报错产生的原因

浙公网安备 33010602011771号