【发布时间】:2017-05-16 00:29:31
【问题描述】:
注释需要类对象而不是该类实例的函数参数的正确方法是什么?
在下面的例子中,some_class 参数应该是一个类型实例(这是一个类),但这里的问题是type 太宽泛了:
def construct(some_class: type, related_data:Dict[str, Any]) -> Any:
...
在some_class 需要一组特定类型对象的情况下,使用type 根本没有帮助。 typing 模块可能需要一个类泛型来执行此操作:
def construct(some_class: Class[Union[Foo, Bar, Baz]], related_data:Dict[str, Any]) -> Union[Foo, Bar, Baz]:
...
在上面的示例中,some_class 是 Foo、Bar 或 Faz 类,而不是它的实例。它们在类树中的位置无关紧要,因为some_class: Class[Foo] 也应该是一个有效的案例。因此,
# classes are callable, so it is OK
inst = some_class(**related_data)
或
# instances does not have __name__
clsname = some_class.__name__
或
# an operation that only Foo, Bar and Baz can perform.
some_class.a_common_classmethod()
对mypy、pytype、PyCharm等应该没问题
如何使用当前的实现(Python 3.6 或更早版本)来做到这一点?
【问题讨论】:
-
如果您需要比
type更具体,请引入元类或抽象基类。 -
@jonrsharpe - 我相信元类可以解决问题,但我在 Python 中还没有达到这个水平。随着 3.6 中变量注解的引入(包括一个
ClassVar来区分实例变量和类变量),我想知道当有这么多注解类实例的方法时,为什么要使用type来注解类对象。也许我必须等待未来的更新或食谱:)。 -
看来我将不得不依赖
typing.Type并执行Foo = TypeVar['Foo', bond=Bar]之类的操作,其中Bar是ABC,那么,以上面的示例为例:def construct(some_class: Type[Foo], ...) -> Foo。我特别不喜欢使用TypeVar,但它似乎是唯一的方法......
标签: python annotations type-hinting python-typing