注释需要类对象而不是该类实例的函数参数的正确方法是什么?
在下面的示例中,some_class
参数应该是一个类型实例(它是一个类),但问题是type
太宽泛了:
def construct(some_class: type, related_data:Dict[str, Any]) -> Any:
...
如果some_class
需要一组特定类型的对象,则使用type
根本没有帮助。 typing
模块可能需要执行此操作的Class泛型:
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或更早版本)来完成?
答案 0 :(得分:12)
要注释作为类的对象,请使用typing.Type
。例如,这会告诉类型检查器some_class
是类Foo
或其任何子类:
from typing import Type
class Foo: ...
class Bar(Foo): ...
class Baz: ...
some_class: Type[Foo]
some_class = Foo # ok
some_class = Bar # ok
some_class = Baz # error
some_class = Foo() # error
请注意,Type[Union[Foo, Bar, Baz]]
和Union[Type[Foo], Type[Bar], Type[Baz]]
完全相同。
如果some_class
可以是多个类中的任何一个,您可能希望使它们都从相同的基类继承,并使用Type[BaseClass]
。请注意,继承现在必须是非虚拟的(mypy对虚拟继承的支持是being discussed)。
编辑确认允许Type[Union[...
。