Python类方法类型提示中为何会遮蔽外部作用域名称?
问题原因解析
你遇到的这个报错,核心是类体作为独立作用域的名字遮蔽规则,和你之前的认知有偏差:
- 类定义时,Python会先执行类体里的所有代码,类体本身是一个局部作用域。当你在类中定义了
def list(self):,这个list就成为了类作用域内的局部名字,直接覆盖了全局作用域里的内置list类型。 - 在类内部的函数参数注解中,Python会优先在当前类作用域查找名字,而不是直接使用全局的内置类型。所以
shadow_by_X_list_method方法参数里的list[int],实际指向的是你自己定义的那个类方法(一个函数对象)——函数不能用下标[int]操作,自然就抛出了TypeError。 - 而之前的
not_shadow方法能正常运行,是因为它定义在list方法之前,此时类作用域里还没有list这个名字,注解里的list会找到全局的内置list类型,所以没问题。
你之前以为类函数只能通过self访问,其实是混淆了类定义阶段的作用域和实例运行阶段的访问方式:
- 实例访问类方法确实需要通过
self.方法名或者类名.方法名; - 但在类定义的过程中,类体里的代码是直接在类作用域内执行的,此时定义的方法名会直接成为该作用域的局部变量,覆盖同名的全局名字。
解决方法
- 最直接的:避免使用内置类型/函数的名字(比如
list、str、dict等)作为类方法名,从根源上避免遮蔽。 - 如果必须用这个名字,可以在注解里明确引用内置类型:
或者在Python3.9之前使用def shadow_by_X_list_method(self, x: __builtins__.list[int]): passtyping.List:from typing import List def shadow_by_X_list_method(self, x: List[int]): pass
内容的提问来源于stack exchange,提问作者Fedor Goncharov
相关产品推荐
相关产品推荐

