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
は、cls
がA
のインスタンスであることを意味しますが、cls
は少なくともサブクラスA
であるクラス/タイプであると言いたいです。
具体的には、パラメーターがDjangoモデルタイプである必要があります。
ここでの他の現在(2016年9月22日)の回答は正しくないようです。 PEP 484(タイプヒントについて)によると、クラスオブジェクトのタイプに関するヒントが存在します。これは Type [C] と呼ばれます。そして、typing
モジュールのドキュメントによると、あなたは typing.Type [C] を使ってあなたが望むものを正確に達成することができます。私はPython 3.5.2。
引用 the PEP :
クラスオブジェクト、特に特定のクラスから継承するクラスオブジェクトについて話したい場合があります。これはType [C]と綴ることができ、Cはクラスです。明確にするために:C(注釈として使用される場合)はクラスCのインスタンスを参照しますが、Type [C]はCのサブクラスを参照します。
そして引用 ドキュメント :
Cで注釈された変数は、タイプCの値を受け入れることができます。対照的に、Type [C]で注釈された変数は、それ自体がクラスである値を受け入れることができます。具体的には、Cのクラスオブジェクトを受け入れます。
そしてあなたの特定の例を参照してください:
import typing
class A(object):
pass
class B(A):
pass
def register(cls: typing.Type[A]):
assert issubclass(cls, A)
register(A)
register(B)
このようなコードは mypy を使用して静的にチェックでき、簡単なケースで機能するはずです。ただし、mypyはまだ作業中であることに注意してください。現在、Type [C]ヒンティングに関していくつかの問題が未解決です。
一般的なケースを解決するには、適切な___subclasscheck__
_を使用してメタクラスを記述する必要があります。可能ですが面倒です。
Djangoモデルクラスの特定のケースでは、明示的なメタクラスがすでに存在しているので、注釈を付けると次のようになります。
_import Django.db.model as model
def register(cls: model.base.ModelBase): ...
_
これは、isinstance(models.Model, models.base.ModelBase)
がtrueであるため機能します。