如何注释属于类对象的类型(而不是类实例)? [英] How to annotate a type that's a class object (instead of a class instance)?
问题描述
注释需要一个类对象而不是该类实例的函数参数的正确方法是什么?
What is the proper way to annotate a function argument that expects a class object instead of an instance of that class?
在下面的示例中,some_class
参数应该是类型实例(它是一个类),但是这里的问题是type
的范围太广:
In the example below, some_class
argument is expected to be a type instance (which is a class), but the problem here is that type
is too broad:
def construct(some_class: type, related_data:Dict[str, Any]) -> Any:
...
在some_class
需要一组特定类型的对象的情况下,使用type
根本没有帮助. typing
模块可能需要执行以下操作的Class泛型:
In the case where some_class
expects a specific set of types objects, using type
does not help at all. The typing
module might be in need of a Class generic that does this:
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]
也应该是有效的情况.因此,
In the example above, some_class
is the Foo
, Bar
or Faz
class, not an instance of it. It should not matter their positions in the class tree because some_class: Class[Foo]
should also be a valid case. Therefore,
# 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等应该没问题.
should be OK to mypy, pytype, PyCharm, etc.
如何使用当前的实现(Python 3.6或更早版本)来完成此操作?
How can this be done with current implementation (Python 3.6 or earlier)?
推荐答案
To annotate an object that is a class, use typing.Type
. For example, this would tell the type checker that some_class
is class Foo
or any of its subclasses:
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支持为正在讨论).
If some_class
could be any of a number of classes, you may want to make them all inherit from the same base class, and use Type[BaseClass]
. Note that the inheritance must be non-virtual for now (mypy support for virtual inheritance is being discussed).
经过编辑以确认是否允许使用Type[Union[...
.
Edited to confirm that Type[Union[...
is allowed.
这篇关于如何注释属于类对象的类型(而不是类实例)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!