問題の歴史:
動的型付けはPythonの最初のバージョンから特徴的です。これは、変数があらかじめ特定のデータ型にバインドされていないことを意味し、JavaやC++のような言語とは異なります。型は実行時に決まります。
問題:
主な難しさは、型の明示的な制御を失うことです。これは、コードを書く段階でのエラー検出を困難にし、特にコードのスケーリング時にランタイムでの論理バグを引き起こす可能性があります。
解決策:
Pythonはこの問題をダックタイピング(オブジェクトがアヒルのように振る舞うなら、それはアヒルです)を通じて解決し、また型アノテーション(タイプヒント)を用いますが、これらのアノテーションは必須ではなく、実行時に検証されることはなく、サードパーティのツールによってのみ検証されます。
コードの例:
x = 42 # int x = "foo" # 現在は文字列 def process(val): return val + val print(process(5)) # 10 print(process("ha")) # haha
主な特徴:
1つの変数を最初にリストとして、その後数値として同じコードブロック内で使用することは可能ですか?それは構文エラーを引き起こしますか?
可能です—構文エラーは発生しません。エラーは、新しいタイプで無効な操作を試みたときにのみ発生します。
x = [1, 2, 3] x = 5 # print(x[0]) # この呼び出しでのみエラーが発生します
Pythonのタイプヒントは、変数が実行時に常に指定された型を持つことを保証しますか?
いいえ—タイプヒントは単なるヒントであり、インタプリタはそれを検証しません。型を検証できるのはリンダーやmypyだけです。
def foo(x: int) -> int: return x + 1 foo("string") # 呼び出しまでエラーは発生しません
関数の型も動的ですか?実行時に関数のシグネチャを変更できますか?
関数は第一級オブジェクトです。関数の型は再定義できますが、シグネチャは変更できません(関数を新しいもので置き換えることは可能です)。
def f(): return 5 f = lambda: "abc" print(f()) # 'abc'
ネガティブケース
あるプロジェクトでは、関数の入力パラメータのタイプがチェックされていなかったため、ユーザーフォームからのデータが文字列として渡され、数値として扱われました。本番環境で予測できないエラーが発生しました。
利点:
迅速なプロトタイピング、短い関数、少ないボイラープレート。
欠点:
デバッグが難しく、エラーが最も予期しない場所で現れることがあります。
ポジティブケース
タイプヒントとmypyによる静的型検証を使用した場合、問題はCI/CDの段階で本番環境に出る前に発見されました。
利点:
潜在的な問題の早期発見、コードの保守の容易さ。
欠点:
追加の検証に時間がかかり、時には少し余分なコードが追加されます。