5

関数アノテーションは、Pythonですでに見つかっている動作と重複しているようです。それだけでなく、それらがとる意味は決して強制されないので、PEP3107に記載されている次のいずれかに使用できます。

  • タイピング情報の提供
  • タイプチェック
  • IDEに、関数が期待して返すタイプを表示させます
  • 関数のオーバーロード/ジェネリック関数
  • 外国語の橋
  • 適応
  • 述語論理関数
  • データベースクエリマッピング
  • RPCパラメータマーシャリング
  • その他の情報
  • パラメータと戻り値のドキュメント

または完全に異なるものですら。

ある意味で、関数アノテーションは、 Pythonのユーモアコレクションの古いジョークを思い出させます。

実際、Pythonはすでにブロック区切り文字をサポートしています。

>
>     if foo: #{
>         foo1();
>         foo2();
>         foo3();
>     #}

その中で

def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
    ...

以下よりも役立つことはありません:

# a: 'x', b: 5 + 6, c: list
def foo(a, b, c):  #-> max(2, 9):
    ...

コメントとは異なり、次のようにコード内からアクセスできるため、関数アノテーションが必要であると主張する人もいるかもしれません。

>>> def spam(a: 'eggs') -> 'ni!':
...     pass
...
>>> spam.__annotations__
{'a': 'eggs', 'return': 'ni!'}

ただし、これと同じ動作は、次のようなデコレータを使用して簡単に実現できます。

def param(**kw):
    def decorator(func):
        def wrap(*args):
            print kw
            func(*args)
        return wrap
    return decorator

def return_(arg):
    def decorator(func):
        def wrap(*args):
            func(*args)
            print arg
        return wrap
    return decorator

@param(a='eggs')
@return_('ni!')
def spam(a):
    pass

spam(None)

# Output:
# -------
## {'a': 'eggs'}
## ni!

Pythonはすでにアノテーションが行うことを実行できるのに、なぜ関数アノテーションに専用の構文が必要なのですか?

編集:その意味が少し不明確であることが判明したので、私は私の質問を少し拡張するつもりです。

私はこの質問を、デコレータではなく関数の注釈について具体的に尋ねています。

@decorator
def spam():
    pass

の略です

def spam():
    pass
spam = decorator(spam)

およびメソッド呼び出し、ここで

self.method(param)

の略です

Class.method(self, param)

これらの2つの省略形の構文ショートカットでは、それらの意味を変えることはできません。既存の代替手段があるのに、なぜそのようなショートカットが必要なのか、私は尋ねていません。それは読みやすさの問題です。関数のアノテーションは、これら2つのショートカットとは少し異なります。

def spam() -> int:
    pass

def spam() -> 'integer':
    pass

人間と同じ意味を持つかもしれませんが、コンピュータと同じ意味を持つことはありません。プログラマーが注釈が何を定義すべきかを知っていたとしても、注釈がそれをどのように定義するかについての合意された定義はありません。さらに、注釈は機能に影響を与えないため、一貫性を保つ必要はありません。

だからここに私の改訂された質問があります:

関数アノテーションが既存の言語機能にアクセスするための変更可能で一貫性のない方法を提供するのに、なぜ専用の構文が必要なのですか?注釈の使用目的が完全に定義されているのに、注釈の使用方法に強制な定義がないのはなぜですか(PEP 3107)。

4

3 に答える 3

6

リンク先の PEP 3107 は、「理論的根拠」セクションで質問に対する回答を提供しているようです。

根拠

Python の 2.x シリーズには、関数のパラメーターと戻り値に注釈を付ける標準的な方法がないため、このギャップを埋めるためにさまざまなツールとライブラリが登場しました。「PEP 318」で導入されたデコレータを利用するものもあれば、関数のドキュメント文字列を解析してそこで注釈を探すものもあります。

この PEP は、この情報を指定する単一の標準的な方法を提供することを目的としており、これまで存在してきたメカニズムと構文の幅広いバリエーションによって引き起こされる混乱を減らします。

于 2012-08-30T18:53:31.443 に答える
6

デコレータ構文のポイントは何ですか? 以前はできなかったことができなくなります。

@staticmethod
def foo():
    pass

ただ

def foo():
    pass
foo = staticmethod(foo)

しかし、デコレータの構文はより優れています。

これら2つのうち、どちらが優れていますか:

@param(a='eggs')
@return_('ni!')
def spam(a):
    pass

def spam(a: 'eggs') -> 'ni!':
    pass

意見は分かれるかもしれませんが、私は後者の方がいいと思います。

于 2012-08-30T18:54:17.363 に答える