33

PEP 3107 の最初の 2 つのセクションを読み終えましたが、この言語にどのような効果があるのか​​まだわかりません。デコレータを使用して関数にメタデータを追加できるようです。例えば

def returns(return_type):
  f.return_type = return_type  # <- adding metadata here
  return f

@returns(Foo)
def make_foo(): ...

メタデータを引数に追加することもできます。次のように、デフォルトの引数を利用すると見栄えがよくなります。

import inspect

def defaults_are_actually_metadata(f):
  names, args_name, kwargs_name, defaults = inspect.getfuncspec(f)
  f.parameter_metadata = dict(zip(names[-len(defaults):], defaults))
  f.__defaults__ = ()
  return f

@defaults_are_actually_metadata
def haul(load="Stuff to be carried.",
         speed_mph="How fast to move the load (in miles per hour)."): ...

少なくとも私の最初の印象は、アノテーションは不必要だということです。デコレーターは、アノテーションができることはすべて (およびそれ以上) 行うことができます。関数にメタデータを追加する場合、デコレーターよりもアノテーションの方が優れているのはなぜですか?

4

3 に答える 3

32

あなたが言及したように、関連する PEP は3107です(この質問に遭遇した他の人がまだ読んでいない場合に備えて、簡単に参照できるようにリンクされています)。

今のところ、注釈は一種の実験であり、一種の進行中の作業です。実際、python-ideas メーリング リストには、このトピックに関する最近のスレッドがあり、参考になるかもしれません。(提供されているリンクは毎月のアーカイブ用のものです。特定の投稿の URL は定期的に変更される傾向があることがわかりました。問題のスレッドは 12 月の初め近くにあり、タイトルは「[Python-ideas] Conventions for function annotations」です。最初の投稿は、12 月 1 日の Thomas Kluyver からのものです。)

そのスレッドの Guido van Rossum の投稿の 1 つから少し引用します。

2012 年 12 月 4 日午前 11 時 43 分、Jasper St. Pierre は次のように書いています。

それはそう。以前に注釈を見たことがありますが、目的がわかりませんでした。これは、なんらかの目標を念頭に置くことなく設計および実装された機能のように見え、コミュニティが目標を自分で発見することになっていました。

グイドの反応:

それとは反対に。すぐに重要と思われるユースケースが多すぎて、どのユースケースが最も重要か、またはそれらをどのように組み合わせるかを判断できなかったため、2 段階のアプローチを取ることにしました。ステップ 1 では、構文を設計しました。 、一方、ステップ 2 では、セマンティクスを設計します。構文が確立されると、人々はさまざまなセマンティクスを自由に試すことができるという考えは非常に明確でした-stdlibではありません。最終的には、これらすべての実験から、stdlib に適したものが出現するという考えもありました。

ジャスパー・セント・ピエール:

では、アノテーションの本来の目的は何だったのでしょうか。PEP はいくつかの提案をしますが、具体的なものは何も残しません。IDE やソース コードを検査する静的解析ツールを支援するために設計されたのでしょうか? コマンド ライン パーサーやランタイムの静的チェッカーなど、アプリケーション自体が特別な動作を提供するために何かを変更する必要がありますか?

グイドの反応:

上記のほとんどすべてがある程度。しかし、個人的には、主な目標は常に、引数と戻り値の型制約 (およびその他の制約) を指定する表記法に到達することでした。私は、型を組み合わせる特定の方法を何度も試してきました。たとえば、list[int] は整数のリストを意味し、dict[str, tuple[float, float, float, bool]] は文字列を 3 つの float と bool のタプルにマッピングする dict を意味する場合があります。しかし、引数の注釈の構文よりも、そのような表記法についてコンセンサスを得る方がはるかに難しいと感じました (これらの 2 つの例にどれだけの異論を持ち込むことができるか考えてみてください :-) -- 私は常に使用したいという強い願望を持っていました。 「var: type = default」と入力し、型をデフォルトと同時に評価されるランタイム式にします。

そして、Ned Batchelder からのちょっとしたユーモア:

私にとって重要な瞬間は、PyCon での初期の Py3k 基調講演 (おそらくダラスかシカゴでの開催だったでしょうか?) でした。Guido は「注釈」という言葉を思い出せず、「ご存知のように、型宣言ではないものです。 ?」:-)

于 2012-12-09T15:19:47.510 に答える
8

最初の段落にすべてが記載されていると思います。

Python の 2.x シリーズには、関数のパラメーターと戻り値に注釈を付ける標準的な方法がないため

(私のものを強調)

これを行う標準的な方法があると、注釈が配置される場所を正確に把握できるという利点があります。

それを行う別の方法があるというあなたの議論については、リスト内包表記に対して同じ議論をすることができます:

out = []
for x in my_iterable:
    out.append(x)
于 2012-12-09T05:06:51.627 に答える
6

それらには 2 つの異なる役割があります。

注釈は、デコレータが関数を変換する間の引数のドキュメント/コメントです。

Python 自体は、注釈に特定の意味や重要性を付与しません。

Python デコレータ ページ

デコレーターは、サブクラスを直接使用したり、装飾されている関数のソース コードを変更したりすることなく、関数、メソッド、またはクラスの機能を動的に変更します。

于 2012-12-09T06:51:22.763 に答える