重複の可能性:
Python での静的型チェックのためのツール
ほとんどの場合、Python で任意の型を選択して好きな場所にドロップし、Duck の型付けに任せることができるという事実が気に入っています。しかし、どうすればコンパイル時間が経過するのを止めることができますか。Unit Tesingに頼らずに、コンパイル時に必要なときに何らかの健全性チェックを強制する方法はありますか?
重複の可能性:
Python での静的型チェックのためのツール
ほとんどの場合、Python で任意の型を選択して好きな場所にドロップし、Duck の型付けに任せることができるという事実が気に入っています。しかし、どうすればコンパイル時間が経過するのを止めることができますか。Unit Tesingに頼らずに、コンパイル時に必要なときに何らかの健全性チェックを強制する方法はありますか?
Pycheckerなどの別のツールを使用して、存在しないメソッドやプロパティの使用などについて警告します。これはコンパイルの一部ではありませんが、VCS の pre-commit フックなど、独自のプロセスの一部として強制できます。
いいえ。Python コンパイラは、変数名のスペルが正しいかどうかさえ知りません (そして、一般的にはできません)。ましてや、各変数、オブジェクト属性、コレクション スロットなどでどの型が pup であるかはわかりません。それを書いている人々は他の優先事項を持っています。ほとんどのコードでは非常に困難から不可能です。非常に単純なケースでは、静的アナライザーはこのようなことを試みることができる場合があります。しかし、実際には、それは不可能です。
コンパイラは Python の型情報を持っていません。ただし、コンパイラに情報を提供するオプションの注釈を言語に追加する可能性については、たとえばここで説明されています。
それまでの間、私はPyCheckerを調べることをお勧めします。
デコレータを悪用して、デバッグモードで異常なタイプの警告を追加できます。
import warnings
import functools
import numbers
debug = True
class TypeWarning(Warning):
pass
def warn_types(*pos_types):
def decorator(func):
if not debug:
return func
@functools.wraps(func)
def wrapper(*args):
for i, (x, t) in enumerate(zip(args, pos_types)):
if not isinstance(x, t):
warnings.warn("Expected %s got %s for argument %d of %s"
% (t.__name__, x.__class__.__name__,
i, func.__name__),
category=TypeWarning, stacklevel=2)
return func(*args)
return wrapper
return decorator
@warn_types(numbers.Number, numbers.Number)
def add(x, y):
return x + y
これにより、機能を損なうことなくプログラマーに警告が表示され、デバッグモードをオフにすることで警告をオフにできます。これらは、プロジェクトのコーディングが終了した後、簡単な検索-置換によって削除することもできます。
>>> print add(3, 4)
7
>>> print add("a", "b")
__main__:1: TypeWarning: Expected Number got str for argument 0 of add
__main__:1: TypeWarning: Expected Number got str for argument 1 of add
ab
Python 3を使用していて、非常に単純になる可能性がある場合にアノテーションを利用できる場合を除いて、一般的なケースでは、これをキーワード引数に拡張することは簡単ではありません。
Python には、他の静的な言語が持つ明確に定義された「コンパイル時間」が実際にはありません。
isinstance()
ただし、 andを使用type()
して、オブジェクトが期待するクラスのインスタンスであることを確認できます。
すべての最初の行を次のようにすることができます。
if not all(isinstance(a, b) for a, b in zip(((x, int), (y, str), (z, float))))
タイプを明示的に宣言できるhttp://code.enthought.com/projects/traits/のようなパッケージを使用できます。
http://cython.org/にコードを書くことができます。
コンパイルは初期化時間であるため、Pythonにはそのようなものはありません。assert
ステートメントを使用して、特定の型が関数に渡されるようにすることができますassert type(foo) == list
。Pythonic とは、取得しているオブジェクトに必要なメソッドがあることを確認することです。たとえば、オブジェクトを繰り返し処理する必要がある場合は、次のようにします。
assert '__iter__' in dir(obj)
簡単な型チェックが必要だと思いますよね?
簡単なデモでお答えします。
>>> m = 7
>>> m.__class__
<type 'int'>
>>> n = 6
>>> o = 6.6
>>> m.__class__ == n.__class__
True
>>> m.__class__ == o.__class__
False
>>> isinstance(o, int)
False
>>> isinstance(m, int)
True
>>>
それが理にかなっていることを願っています。