web-dev-qa-db-ja.com

PythonデコレータはJavaアノテーション、またはJava Aspectsと同じですか?

PythonデコレータはJavaアノテーションまたはSpring AOPやAspect Jのようなもの)と同じまたは類似していますか、または根本的に異なりますか?

44
bn.

Pythonデコレータは、関数を別の関数に渡し、最初の関数を結果で置き換えるための単なる構文上の砂糖です。

@decorator
def function():
    pass

の構文糖

def function():
    pass
function = decorator(function)

Javaアノテーション自体はメタデータを格納するだけなので、動作を追加するためにJavaアノテーションを検査する必要があります。

Java AOPシステムはJavaの上に構築された巨大なものであり、デコレータはセマンティクスがほとんどまたはまったく付加されていない単なる言語構文であり、実際にそれらを比較することはできません。

57
Pavel Anossov

これは非常に有効な質問であり、これらの両方の言語で同時に手を出す人は誰でも受けることができます。私はpython自分自身に時間を費やしてきましたが、最近Javaでスピードを上げています。この比較についての私の見解です。

Javaアノテーションは-それだけです:アノテーション。それらはマーカーです。マーク/注釈を付けている基になるオブジェクトに関する追加のメタデータのコンテナー。それらの単なる存在は、基礎となる実行フローを変更しないか、または基礎の上に何らかのカプセル化/ラッパーを追加しません。では、どのように役立つのでしょうかそれらは-注釈プロセッサによって読み取られ、処理されます。それらに含まれるメタデータは、カスタム作成された注釈プロセッサによって使用され、生活を容易にするいくつかの補助機能を追加できます。ただし、繰り返しになりますが、これらは基礎となるNORラップの実行フローを変更しません。

「実行フローを変更しない」というストレスは、pythonデコレータを使用した人には明らかです。Pythonデコレータ、Javaアノテーションは、フードの下ではかなり異なります。これらは、ユーザーが望むように、基になるものを取り囲み、その周りを包み込みます。彼らはそれを行うことを選択します。彼らは下層を取り、それを包み込み、下層をラップされたもので置き換えます。

これでthatは、Javaでのアスペクトの動作と非常によく似ています!アスペクト自体は、そのメカニズムと柔軟性の点でかなり進化しています。しかし、本質的には何をしているのか-「アドバイスされた」方法(私は春のAOP命名法で話しているが、それがAspectJにも当てはまるかどうかわからない)を取り、機能を述語などでラップし、プロキシ」は、ラップされた「推奨」メソッドです。

これらの熟考は、全体像を把握するのに役立つように、非常に抽象的な概念的なレベルであることに注意してください。より深く掘り下げていくと、これらのすべての概念(デコレーター、アノテーション、アスペクト)にはかなり複雑なスコープが含まれます。しかし、抽象的なレベルでは、それらは非常によく似ています。

[〜#〜] tldr [〜#〜]

ルックアンドフィールに関しては、pythonデコレータはJavaアノテーションと同様に考えることができますが、内部では、アスペクトの動作と非常によく似ています。 Javaで。

14
Shreyas

私はどちらも同じように使用しています。デバッグまたはテストオプションをオン/オフにするためです。

例(Pythonデコレータ):

def measure_time(func):
    def _measure_time(*args, **kwargs):
        t0 = time.time()
        ret = func(*args, **kwargs)
        print "time=%lf" % (time.time()-t0)
        ...
        return ret
    return _measure_time


@measure_time
def train_model(self):
    ...

Java注釈の場合、 getAnnotationなど)を使用します は、同様のジョブまたはより複雑なジョブを実行できます。

2
鄭大大

PythonデコレータとJavaアノテーションは同じ構文を共有しますが、2つの非常に異なる目的に使用されます!これらは互換性がないため、互換性がありません!

最近のプロジェクトでは、Java注釈セマンティクスをpythonスクリプトで使用する必要があり、それをエミュレートする方法を検索したところ、これが見つかりました。

Pythonには、「Docstring」と呼ばれる機能があります!

モジュール、クラス、または関数の最初の行でなければならない特別なコメント行にすぎません。

コメント行と同様に、任意の形式のテキストを使用できます。しかし、この場合、それが私にとって特別なのは、python instrospection !!

つまり、Java注釈のように機能します。これも、Javaリフレクションを使用して、そこから運ばれたメタデータに対応する必要があります。

短い例に従ってください:

ソースa.py

```
def some_function():
    '''@myJavaLikeAnnotation()'''
    ... (my function code) ...
```

ソースb.py(@myJavaLikeAnnotacion()を処理する必要がある場所):

import a

for element_name in dir(a):
    element = getattr(a, element_name)
    if hasattr(element, '__call__'):
        if not inspect.isbuiltin(element):
            try:
                doc = str(element.__doc__)
                if not doc == '@myJavaLikeAnnotation()':
                    # It don't have the 'Java like annotation'!
                    break

                ... It have! Do what you have to do...  
            except:
                pass

明らかにその不利な点は、 'python Java like annotations'で使用するすべてのメタデータを自分で解析する必要があることです!

0
Júlio Oliveira