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

关于这个递归报错的理解:

代码的执行流程:

  1. ud['V'] 的调用触发了 __getitem__ 方法,因为在 UserDictSub 类中没有直接定义 __getitem__ 方法,所以从父类 UserDict 继承的 __getitem__ 方法被调用。
  2. __getitem__ 方法中,检查键 'V' 是否在 self.data 中,这里 self.data{'A': 'letter A'}。因为 'V' 不在 self.data 中,所以继续执行下面的代码。
  3. __getitem__ 方法中,检查是否定义了 __missing__ 方法。由于UserDictSub定义了 __missing__ 方法,所以执行 self.__class__.__missing__(self, key)
  4. __missing__ 方法中,执行 self[_upper(key)]。此时 key'V'
  5. 调用 _upper('V'),这将执行 return self['V'.upper()]
  6. 回到步骤1,递归调用 __getitem__ 方法,继续执行之前的步骤,直到达到 Python 解释器的最大递归深度,抛出 RecursionError

这就是递归报错产生的原因

posted @ 2024-02-04 15:16  AlphaGeek  阅读(6)  评论(0)    收藏  举报