如何编写类装饰器使类型检查器识别装饰后类的超类型?
问题分析
你遇到的问题是:尽管装饰器声明返回Type[Base],但Pyre仍将装饰后的C识别为Type[C],导致传入takes_base时类型不匹配。这是因为静态类型检查器没有自动追踪到装饰器对原类类型的替换,需要更明确的类型注解来确认返回类的类型归属。
解决方案
以下两种方案可以解决这个问题:
方案1:使用cast显式指定返回类型
通过typing.cast强制告诉类型检查器,装饰器返回的类确实属于Type[Base]类型:
from typing import TypeVar, Type, cast T = TypeVar("T") class Base: pass def decorate_class(cls: Type[T]) -> Type[Base]: class Ret(Base, cls): pass return cast(Type[Base], Ret) @decorate_class class C: pass def takes_base(inst: Type[Base]) -> Type[Base]: return inst takes_base(C) # Pyre不再报错
方案2:使用交集类型保留原类信息
如果需要同时保留原类的类型特性(比如调用原类的方法),可以用交集类型声明返回值既是Base的子类,也是原类的子类:
from typing import TypeVar, Type T = TypeVar("T") class Base: pass def decorate_class(cls: Type[T]) -> Type[Base] & Type[T]: class Ret(Base, cls): pass return Ret @decorate_class class C: pass def takes_base(inst: Type[Base]) -> Type[Base]: return inst takes_base(C) # 类型检查通过,因为交集类型兼容Type[Base]
内容的提问来源于stack exchange,提问作者danben
相关产品推荐
相关产品推荐

