Python类型提示:如何判断X是Foo的子类?

时间:2015-08-25 13:54:20

标签: python python-3.x django-models type-hinting

我应该如何在Python中为类类型编写类型提示? 请考虑以下代码:

class A(object):
    pass

class B(A):
    pass

def register(cls: type[A]):
    assert issubclass(cls, A)

 register(A)
 register(B)

type[A]是否有正确的写法? 如果我只使用cls: A,则表示clsA的实例,但我想说cls是一个类/类型,在最少的子类A

具体来说,我要指出的是参数应该是 一个Django模型类型。

2 个答案:

答案 0 :(得分:29)

似乎其他当前(2016年9月22日)答案不正确。根据PEP 484(关于类型提示),存在类对象类型的提示,称为Type[C]。根据{{​​1}}模块的文档,您可以使用typing.Type[C]来实现您想要的目标。我自己使用的是Python 3.5.2。

引用the PEP

  

有时你想谈论类对象,特别是从给定类继承的类对象。这可以拼写为Type [C],其中C是一个类。澄清:虽然C(当用作注释时)引用类C的实例,但类型[C]引用C的子类。

并引用the docs

  

用C注释的变量可以接受类型C的值。相反,使用Type [C]注释的变量可以接受类本身的值 - 具体来说,它将接受C的类对象。

参考你的具体例子:

typing

您可以使用mypy静态检查此类代码,并且它应该在简单的情况下工作 - 请注意mypy是一项正在进行的工作,截至目前,有几个关于Type [C]提示的问题。

答案 1 :(得分:3)

要解决一般情况,您必须使用合适的__subclasscheck__编写元类。可能,但很麻烦。

在Django模型类的特定情况下,已经存在一个显式元类,因此注释应该完成这项工作:

import django.db.model as model

def register(cls: model.base.ModelBase): ...

这将有效,因为isinstance(models.Model, models.base.ModelBase)是真的。