【发布时间】:2018-09-10 00:56:27
【问题描述】:
我定义了一个抽象基类BaseRepository,它充当具有指定超类型Foo 的项的集合。
BaseRepository 中的便捷类方法经过注释/类型提示可与 Foo 类型的对象一起使用。这是一个最小的例子:
from abc import ABCMeta, abstractmethod
NoReturn = None
class Foo(object):
pass # simple data holding object
class BaseRepository(object, metaclass=ABCMeta):
# May be filled with subtypes of `Foo` later
_items = None # type: List[Foo]
@classmethod
def get_item(cls) -> Foo:
return cls._items[0]
@classmethod
@abstractmethod
def _load_items(cls) -> NoReturn:
pass
现在有多个静态实现(例如SubRepository),每个都应该使用自己的项目类型(例如Bar),它们是原始泛型类型Foo的子类。
class Bar(Foo):
pass # Must implement Foo in order for BaseRepository's methods to work
def load_some_bars():
return [Bar(),Bar()]
class SubRepository(BaseRepository):
# Inherits `get_item` from BaseRepository
@classmethod
def _load_items(cls) -> NoReturn:
cls._items = load_some_bars()
存储库是静态的,这意味着它们不会被实例化,而是用作命名空间,以便正确访问我从 YAML 配置文件加载的项目。主要好处是我可以创建其中一个SubRepositories 并简单地覆盖反序列化方法_load_items,并且生成的存储库将具有来自基类的所有便利方法。因为我需要确保所有这些SubRepositories 与具有特定接口的项目Foo 一起使用,以便BaseRepository 方法正常运行,所以SubRepositories 必须与从Foo 继承的项目一起使用。
Java 或 C# 等强类型语言具有 通用集合 的概念,其中子类集合中的元素都假定为特定类型。
Python中的类型提示是否可能相同?
特别是,我希望以最小的努力将SubRepository 中继承的get_item 方法提示为Bar(不要仅仅为了类型提示而覆盖它)。最佳情况下,正确的返回值应该由 PyCharm 检测。
目前,即使 SubRepository 拥有 Bar 项目,我在 PyCharm 中的自动完成功能只显示 Foo 的成员。
我读到了 typing.Generic 和 TypeVar,但我不确定在这种情况下如何使用它们。
【问题讨论】:
-
可以使用 Python v3.5+ 吗?您也许可以使用typing 模块解决问题。我会让我的无知表现出来....您是否试图将其他语言的范式强加到 Python 中?您是实例化您的类还是将对象本身用作容器?
-
是的,我正在寻找打字解决方案。我读到了
Generic[...]和TypeVar,但不确定它们在这种情况下有何帮助。对象本身是带有静态项的静态类,是的,因为它们代表我从 yaml 文件加载的配置值。 -
需要明确的是,当方法套件只是对
super的方法的调用时,仅仅为了类型提示而重写该方法太费力了? -->def get_item(cls) -> Bar: return super().get_item() -
当然,这是我目前的解决方法。我可能还会查看 .pyi 文件,这些文件允许在单独的文件中指定类型提示,以防止混乱。但是,我正在寻找最惯用的解决方案,如果现在我们终于在 python 中拥有伪强类型,如果没有办法让它工作,我会感到惊讶 ????。顺便说一句,感谢您的编辑,感谢。
-
...So if you really, really want type hints, there's really no alternative to specifying them everywhere you want them.来自stackoverflow.com/a/22389249/2823755
标签: python generics inheritance collections types