如何注释作为类对象(而不是类实例)的类型? [英] How to annotate a type that's a class object (instead of a class instance)?

查看:26
本文介绍了如何注释作为类对象(而不是类实例)的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注释需要类对象而不是该类的实例的函数参数的正确方法是什么?

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 模块可能需要一个执行此操作的类泛型:

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_classFooBarFaz 类,而不是它.它们在类树中的位置应该无关紧要,因为 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)?

推荐答案

要注释属于类的对象,请使用 typing.Type.例如,这会告诉类型检查器 some_class 是 class Foo 或其任何子类:

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[....

这篇关于如何注释作为类对象(而不是类实例)的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆