python class 中的方法可以用 subclass 定义的类型注释吗?
Can a method in a python class be annotated with a type that is defined by a subclass?
我有一个超类,它有一个由其子类共享的方法。但是,此方法应该 return 具有在子类上定义的类型的对象。我希望方法的 return 类型被静态注释(不是动态类型),因此使用子类的代码可以受益于对 return 值的 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
引用。
有什么方法可以同时实现共享超类实现和精确子类 return 类型?
将 AbstractRepository
定义为通用 class。
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
仅使用 class 属性,因此可以——并且可以说应该——是一种 class 方法。)
我有一个超类,它有一个由其子类共享的方法。但是,此方法应该 return 具有在子类上定义的类型的对象。我希望方法的 return 类型被静态注释(不是动态类型),因此使用子类的代码可以受益于对 return 值的 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
引用。
有什么方法可以同时实现共享超类实现和精确子类 return 类型?
将 AbstractRepository
定义为通用 class。
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
仅使用 class 属性,因此可以——并且可以说应该——是一种 class 方法。)