typing
モジュール(または他のモジュール)は、isinstance()
と同様に、実行時に変数を型チェックするAPIを示しますが、typing
で定義された型クラスを理解していますか?
次のようなものを実行したいと思います。
from typing import List
assert isinstance([1, 'bob'], List[int]), 'Wrong type'
typing
モジュールにはそのような関数はなく、おそらく存在しないでしょう。
オブジェクトがクラスのインスタンスであるかどうか(「このオブジェクトはクラスのコンストラクターによって作成された」という意味のみ)を確認するのは、タグ付けをテストするだけの簡単なことです。
ただし、オブジェクトがタイプの「インスタンス」であるかどうかを確認することは、必ずしも決定可能ではありません。
assert isinstance(foo, Callable[[int], str]), 'Wrong type'
foo
のタイピング注釈を調べるのは簡単ですが(lambda
でない場合)、ライスの定理によれば、それらに準拠しているかどうかを確認することは一般に決定不可能です。
List[int]
のような単純なタイプでも、テストは簡単に非効率になりすぎて、最小のおもちゃの例以外には使用できなくなります。
xs = set(range(10000))
xs.add("a")
xs.pop()
assert isinstance(xs, Set[int]), 'Wrong type'
型チェッカーがこの操作を比較的効率的な方法で実行できるようにする秘訣は、保守的であることです。型チェッカーは、foo
が常にint
を返すことを証明しようとします。失敗した場合、プログラムが有効である可能性がある場合でも、プログラムを拒否します。つまり、この関数は完全に安全ですが、拒否される可能性があります。
def foo() -> int:
if "a".startswith("a"):
return 1
return "x"
私は似たようなものを探していて、ライブラリ typeguard を見つけました。これにより、必要な場所でランタイムタイプチェックを自動的に実行できます。質問のようにタイプを直接チェックすることもサポートされています。ドキュメントから、
from typeguard import check_type
# Raises TypeError if there's a problem
check_type('variablename', [1234], List[int])