python 3の新しい特性の詳細:関数注記(Function Annotations)とタイプ注記

4523 ワード

文書ディレクトリ
  • 導入
  • 関数注記
  • 変数注記
  • 静的タイプチェックモジュールmypy
  • まとめ
  • 参照
  • 導入
    python 3のコードを読むと、次のようなプログラムが表示されます.
    def add(x: int, y: int) -> int:
        return x+y
    

    初歩的にはpython 2と比較して,この関数は定義上3 int多くなった.最初の2つのintは入力データのタイプを表し、「->」記号の後ろのintは戻り値のタイプを表す.
    pythonでは、変数タイプを強制的に明記する必要はありません.python 3のこの新しい文法は、変数のタイプを直接説明できるようですか?
    関数注記
  • 関数注記の説明
  • このような「関数パラメータにおける変数タイプと戻り値タイプを明らかにする」という構文はpython 3のいわゆる「関数注釈」[1]である.
    注記「adding arbitrary metadata annotations to Python functions」にすぎず、追加されたこれらの「タイプ宣言」は、強制的に要求されるものではなく、追加情報です.
    そして、「関数注釈」の目的は、解釈器に見せることではなく、見せることです.したがって、タイプが間違っていても、コンパイラは次のようにエラーを報告しません.
    def add(x: int, y: int) -> int:
        return x+y
    
    z = add(3.14, 1.23)
    

    python 3を使う.0以上のバージョンでこのプログラムを実行しても、実パラメータが浮動小数点型であっても、パラメータが整数型であることは間違いありません.最終zの値は4.37である.
    Python解釈器は、これらの注釈のために追加の検証を提供するものではなく、検査作業のタイプはありません.つまり、これらのタイプの注釈は加算されず、あなたのコードには何の影響もありません[2].
    「関数注記」の役割は、(1)プログラマが表示しやすいこと、(2)IDEの設計者がコードチェックに使用できることだけです.
  • 関数注記
  • へのアクセス方法
    どのようにして関数のタイプ注釈を得るのでしょうか.実は簡単です.__annotations__を使用すればいいです.例えば、上記で定義した関数addのように、次のコードを実行します.
    add.__annotations__
    

    得られた結果は{'return': int, 'x': int, 'y': int}であった.
    結果には、戻り値と各パラメータのタイプ要件が得られます.
    変数注記
    変数注記は、「adding syntax to Python for annotating the types of variables(including class variables and instance variables)」です.簡単に言えば、変数(クラス内の変数とインスタンス変数を含む)にタイプ注記を追加します.具体的にはpython 3を用いることに注意する.6以上のバージョンで実行:
  • int/str/float変数注記
  • a1: int # a1 int   ,    
    a2: int = 123 # a2 int   ,   123
    b1: str # b1 str   ,    
    b2: str = 'hello'# b2 str   ,   hello
    c1: float# c1 float   ,    
    c1: float = 3.14# c1 float   ,   3.14
    

    pythonの解釈器は変数の実際の「タイプチェック」を行わないことに注意してください.この注釈の役割は、読みやすいようにするためだけです(またはIDEが自分でチェックします).したがって、次のプログラムの実行は正しいので、エラーは報告されません.
    a1: int 
    a2: int = 123 
    a1 = 3.14
    a2 = 'hello'
    
  • list/tuple/dict変数注記
  • from typing import List, Tuple, Dict
    
    a1: List[int] # a1   list,       int  ,    
    a2: List[str] = ['1','2','3']# a2   list,       int  ,   ['1','2','3']
    b1: Tuple[int] # a1   tuple,       int  ,    
    b2: Tuple[float] = (1.1,2.2,3.3)# a2   tuple,       float  ,   [1.1,2.2,3.3]
    c1: [Dict[str, int]] = {} # c1   dict,  key str  ,value int ,    
    c2: [Dict[str, int]] = {'a':1, 'b':2, 'c':3} # c1   dict,  key str  ,value int ,   {'a':1, 'b':2, 'c':3}
    

    同じように、注釈のタイプによって来なくても、間違いを報告することはありません.
  • 変数注記
  • へのアクセス方法
    プログラムに明示されているすべての注釈変数は、次のように__annotations__によってアクセスできます.
    >>> __annotations__ #          
    
    {'a1': typing.List[int], 'a2': typing.List[str], 'b1': typing.Tuple[int], 'b2': typing.Tuple[float], 'c1': [typing.Dict[str, int]], 'l': typing.List[int], 'c2': [typing.Dict[str, int]]}
    

    静的タイプチェックモジュールmypy
    解釈器が注釈タイプが一致しない場合をエラーで報告しない以上、タイプが一致しない場合をどのようにチェックしますか?
    サードパーティモジュールmypyは、タイプ注記を作成することを前提として、タイプチェックを行うことができます.具体的な例は以下の通りです.
  • mypy
  • をインストール
    pip install mypy
    
  • はtestを書きます.pyプログラム、以下に示す
  • def add(x: int, y: int) -> int:
        return x+y
    
    z: int
    z = 'hello'
    z = add(3.14, 1.23)
    
  • mypy対test.pyタイプチェック
  • CMDでは、コマンドmypy test.pyでチェックすると、出力エラーメッセージは以下のように表示されます.
    mypy test.py
    
    test.py:5: error: Incompatible types in assignment (expression has type "str", variable has type "int")
    test.py:6: error: Argument 1 to "add" has incompatible type "float"; expected "int"
    test.py:6: error: Argument 2 to "add" has incompatible type "float"; expected "int"
    

    mypyプロンプト
  • 5行目1エラー.z変数はintタイプとして明示されているがstrの「hello」
  • に付与されているためである.
  • 6行目の2つのエラーは、関数の2つの変数がintとして明示されているためですが、ここではfloatタイプの2つのデータ
  • が送られます.
    まとめ
    python3.0は関数注記を導入し、python 3.6変数注記が導入されました.後でこの文法は変わるかもしれませんが、筆者が書くときはpython 3.7上の実験で述べたように,本論文では正しい.
    それらはpythonをますますC/C++のようにして、将来pythonはまた汎用型を導入しますか?これでpythonはますますJavaのようになりました...
    リファレンス
  • [1] PEP 3107 – Function Annotations. https://www.python.org/dev/peps/pep-3107/
  • [2] https://zhuanlan.zhihu.com/p/37239021
  • [3] PEP 526 – Syntax for Variable Annotations. https://www.python.org/dev/peps/pep-0526/