Python 3.11 typing.Any可作基类:旨在避免哪些类型检查错误?
Python 3.11中
typing.Any作为基类的特性用途 根据Python官方文档的说明:
3.11版本变更:
Any现在可用作基类,这有助于避免高度动态或支持鸭子类型的类引发的类型检查错误。
你测试的这段代码:
import typing class Foo: def __getattr__(self, attr: str) -> typing.Any: if attr == 'bar': return 5 raise AttributeError(attr) def print_bar(foo: Foo) -> None: print(foo.bar)
在Python 3.10.6搭配mypy 0.971下没报错,是因为mypy对实现了__getattr__的类,默认会放宽未定义属性的类型检查——它知道这类会动态处理属性访问,所以不会因为访问foo.bar而报错,这和Any作为基类的新特性无关。
这个新特性真正解决的是以下这类场景:
- 当你需要创建一个完全动态的类,希望类型检查器不对该类实例的任何属性、方法访问做校验时,在Python 3.11之前,你无法通过继承
Any来实现,只能通过其他方式绕开(比如给类标注TypeVar或者直接用Any作为类型注解)。 - 比如在3.11之前,下面的代码会触发mypy错误:
import typing # Python 3.11之前这行代码本身不合法,且mypy会报错 class DynamicClass(typing.Any): pass def use_dynamic(obj: DynamicClass) -> None: # mypy会提示DynamicClass没有random_method方法 obj.random_method() # mypy会提示无法给DynamicClass添加未定义的属性 obj.new_attr = 123
而在Python 3.11之后,继承Any的类会被类型检查器视为“完全动态”的类型,上述代码不会再触发任何类型检查错误——因为DynamicClass继承自Any,其实例的所有操作都会被当作Any类型处理,跳过校验。
- 另外,对于一些鸭子类型兼容场景,如果你希望某个类可以被当作任意类型使用(比如适配多个不同类型的接口,不需要严格的类型定义),继承
Any可以让你避免大量的类型忽略注释(比如# type: ignore)。
内容的提问来源于stack exchange,提问作者Daniel Walker
相关产品推荐
相关产品推荐

