Python 3.6の変数アノテーションとは何ですか?


83

Python3.6がリリースされようとしています。PEP 494-Python 3.6のリリーススケジュールには12月末が記載されているため、Python 3.6の新機能を調べて、変数の注釈に記載されていることを確認しました。

PEP 484は、関数パラメーターの型注釈、別名型ヒントの標準を導入しました。このPEPは、クラス変数やインスタンス変数などの変数のタイプに注釈を付けるための構文をPythonに追加します。

primes: List[int] = []

captain: str  # Note: no initial value!

class Starship:
     stats: Dict[str, int] = {}

関数アノテーションの場合と同様に、Pythonインタープリターは変数アノテーションに特定の意味を付加せず__annotations__、クラスまたはモジュールの特別な属性にのみ格納します。静的に型付けされた言語での変数宣言とは対照的に、注釈構文の目標は、抽象構文ツリーと__annotations__属性を介してサードパーティのツールとライブラリの構造化型メタデータを指定する簡単な方法を提供することです。

したがって、私が読んだものから、それらはPython 3.5からの型ヒントの一部であり、Python3.5の型ヒントとはで説明されています。

私はcaptain: strとのclass Starship例に従いますが、最後の例についてはよくわかりません:どのようにprimes: List[int] = []説明しますか?整数のみを許可する空のリストを定義していますか?


9
型ヒントは型チェックを行いません。primes: List[int] = []は空のリストprimes = []です。違いは、あなたがしていることであると主張していることprimes を意図しているだけ含まれているintSとサードパーティのアプリケーションは、この主張を検証するために、あなたのプログラムを確認してください入力かもしれませんが、あなただけの書き込みと同じだ任意のPythonインタプリタ内のコードを実行するとprimes = []、したがって、やってはprimes: List[int] = []; primes.append("string")まだあります有効です。
バクリウ2016年

2
@バクリウはい、良い点です。ジムFasarakis-ヒリアードはに彼の答えで説明したようPythonの3.5でタイプヒントは何タイプヒントは、なぜ型チェッカーを支援、文書化に役立つとIDEは、より正確かつ堅牢なツールを開発を支援します。撮影PEP 526 -変数注釈の構文Pythonは動的型付け言語のままになります、と著者はこれまでにも、慣例により、タイプヒントを必須にする欲求を持っていません
fedorqui'SOは害をやめる '2016

1
これはあなたの質問に答えますか?Python 3.5の型ヒントとは何ですか?
AMC

回答:


46

:との間のすべてが=型ヒントであるためprimes、実際にはとして定義されList[int]、最初は空のリストに設定されます(stats最初は空の辞書であり、として定義されますDict[str, int])。

List[int]そしてDict[str, int]次の構文の一部ではありませんが、これらはすでにPythonの3.5タイピングのヒントPEPで定義されていました。3.6 PEP 526 –変数注釈の構文提案は、同じヒントを変数に付加するための構文のみを定義します。コメント付きの変数に型ヒントのみを添付できるようになる前(例primes = [] # List[int])。

ListDictはどちらもジェネリック型であり、特定の(具体的な)コンテンツを含むリストまたはディクショナリマッピングがあることを示します。

の場合List[...]リスト内のすべての要素のタイプである「引数」(構文内の要素)は1つだけです。の場合Dict、最初の引数はキータイプで、2番目の引数は値タイプです。したがって、リスト内のすべてのprimesは整数であり、ディクショナリ内のすべてのキーと値のペアstats(str, int)ペアであり、文字列を整数にマッピングします。

参照typing.Listtyping.Dict定義、上のセクションジェネリック医薬品、など- PEP 483種類のヒントの理論を

関数の型ヒントと同様に、それらの使用はオプションであり、注釈と見なされます(これらをアタッチするオブジェクトがある場合、モジュールのグローバルとクラスの属性ですが、関数のローカルではありません)__annotations__。属性を介してイントロスペクトできます。これらの注釈には任意の情報を添付できます。タイプのヒント情報に厳密に限定されるわけではありません。

あなたは完全な提案を読みたいと思うかもしれません; 新しい構文に加えて、いくつかの追加機能が含まれています。たとえば、そのようなアノテーションがいつ評価されるか、それらをイントロスペクトする方法、クラス属性とインスタンス属性として何かを宣言する方法を指定します。


タイプヒントは、コードの実行方法(obj.__annotations__属性を除く)に影響を与えないため、一種の「機械可読」コメントと見なすことができますか?
iBug 2018

1
@iBug:とにかくコメントが人間が読める注釈である限り、注釈は機械が読めるコメントです。:-)
MartijnPieters

56

変数アノテーションとは何ですか?

変数アノテーションは# typePEP 484;で定義されているように、コメントの次のステップにすぎません。この変更の背後にある理論的根拠は、PEP526それぞれのセクションで強調されています

したがって、タイプをヒントにする代わりに、次のようにします。

primes = []  # type: List[int]

の形式の割り当てで型に直接注釈を付けることができるように、新しい構文が導入されました。

primes: List[int] = []

@Martijnが指摘したように、これはで使用可能な型を使用して整数のリストを示し、typingそれを空のリストに初期化します。

それはどのような変化をもたらしますか?

導入された最初の変更は、文字の後にスタンドアロンで、またはオプションで値を割り当てながら注釈を付けることができる、タイプで名前に注釈を付けることができる新しい構文でし:た。

annotated_assignment_stmt ::=  augtarget ":" expression ["=" expression]

したがって、問題の例:

   primes: List[int] = [ ]
#    ^        ^         ^
#  augtarget  |         |
#         expression    |
#                  expression (optionally initialize to empty list)

新しい構文とともに、追加の変更も導入されました。モジュールとクラスには、タイプメタデータが添付さ__annotations__れた属性があります(PEP 3107以降の関数のように-関数アノテーション)。

from typing import get_type_hints  # grabs __annotations__

現在__main__.__annotations__、宣言されたタイプを保持しています。

>>> from typing import List, get_type_hints
>>> primes: List[int] = []
>>> captain: str
>>> import __main__
>>> get_type_hints(__main__)
{'primes': typing.List<~T>[int]}

captainモジュールでもアクセスできるタイプのみが返されるget_type_hintsため、現在は表示されませんget_type_hints。つまり、最初に値が必要です。

>>> captain = "Picard"
>>> get_type_hints(__main__)
{'primes': typing.List<~T>[int], 'captain': <class 'str'>}

を使用print(__annotations__)すると表示され'captain': <class 'str'>ますが、__annotations__直接アクセスするべきではありません。

同様に、クラスの場合:

>>> get_type_hints(Starship)
ChainMap({'stats': typing.Dict<~KT, ~VT>[str, int]}, {})

ここで、aChainMapは、特定のクラス(最初のマッピングにある)のアノテーションと、そのクラスmro(結果として生じるマッピング、{}オブジェクト)にある基本クラスで定義されているすべてのアノテーションを取得するために使用されます。

新しい構文にClassVar加えて、クラス変数を示す新しいタイプが追加されました。うん、statsあなたの例では、実際にはインスタンス変数であり、ではありませんClassVar

使用を余儀なくされますか?

からの型ヒントと同様にPEP 484、これらは完全にオプションであり、型チェックツール(およびこの情報に基づいて構築できるその他のもの)に主に使用されます。Python 3.6の安定バージョンがリリースされたときに暫定的になるため、将来的に小さな調整が追加される可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.