微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python 类中的方法可以用子类定义的类型进行注释吗?

如何解决python 类中的方法可以用子类定义的类型进行注释吗?

我有一个超类,它有一个由其子类共享的方法。但是,此方法应返回一个对象,其类型在子类上定义。我希望方法的返回类型是静态注释的(不是动态类型),以便使用子类的代码可以受益于 mypy 对返回值的类型检查。但是我不想为了提供它的类型注释而重新定义子类上的通用方法。使用 python 类型注释和 mypy 可以实现吗?

像这样:

from typing import Type

class AbstractModel:
    pass

class OrderModel(AbstractModel):
    def do_order_stuff():
        pass

class AbstractRepository:
    model: Type[AbstractModel]

    def get(self) -> model:
        return self.model()

class OrderRepository(AbstractRepository):
    model = OrderModel


repo = OrderRepository()
order = repo.get()

# Type checkers (like mypy) should recognize that this is valid
order.do_order_stuff()

# Type checkers should complain about this; because `OrderModel`
# does not define `foo`
order.foo()

这里的棘手之处在于 get() 是在超类 AbstractRepository 上定义的,它还不知道 model 的类型。 (并且 -> model 注释失败,因为尚未指定 model 的值)。

model 的值由子类指定,但子类没有(重新)定义 get() 以提供注释。看起来这应该是静态可分析的;虽然这有点棘手,因为它需要静态分析器跟踪从超类到子类的 model 引用。

有什么方法可以同时实现共享超类实现和精确的子类返回类型?

解决方法

AbstractRepository 定义为泛型类。

from typing import TypeVar,Generic,Type,ClassVar


T = TypeVar('T')

class AbstractRespotitory(Generic[T]):
    model: ClassVar[Type[T]]

    @classmethod
    def get(cls) -> T:
        return cls.model()

get 仅使用类属性,因此可以——而且可以说应该——是类方法。)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。