Декораторы Python одинаковы или похожи или принципиально отличаются от аннотаций Java или что-то вроде Spring AOP или Aspect J?
Является ли Python Decorator таким же, как аннотация Java, или Java с аспектами?
Ответ 1
Декораторы Python - это просто синтаксический сахар для передачи функции другой функции и замены первой функции на результат:
@decorator
def function():
pass
- синтаксический сахар для
def function():
pass
function = decorator(function)
Java-аннотации сами по себе просто хранят метаданные, у вас должно быть что-то, что проверяет их, чтобы добавить поведение.
Системы Java AOP - это огромные вещи, построенные на вершине Java, декораторы - это просто синтаксис языка, в котором мало привязаны к семантике, вы не можете реально сравнивать их.
Ответ 2
Это очень актуальный вопрос, который может получить любой, кто увлекается обоими этими языками одновременно. Я провел некоторое время на python и недавно освоил Java, и вот мое сравнение.
Java-аннотации - это просто аннотации. Это маркеры; контейнеры дополнительных метаданных о базовом объекте, который они помечают/аннотируют. Их простое присутствие не изменяет поток выполнения базового объекта или не добавляет инкапсуляцию/оболочку какого-либо вида поверх базового. Так как они помогают? Они читаются и обрабатываются обработчиками аннотаций. Содержащиеся в них метаданные могут использоваться обработчиками пользовательских аннотаций для добавления некоторых вспомогательных функций, облегчающих жизнь; НО, и опять же, они НИКОГДА не изменяют поток выполнения базового, NOR оборачиваются вокруг них.
Упор на "не изменяющийся поток выполнения" будет понятен тому, кто использовал декораторы Python. Декораторы Python, хотя и похожи на Java-аннотации по внешнему виду, совсем другие. Они берут базовый инструмент и оборачиваются вокруг него любым способом, по желанию пользователя, возможно, даже полностью избегая запуска самого базового пакета, если кто-либо решит это сделать. Они берут основу, оборачиваются вокруг нее и заменяют основу на завернутые. они эффективно "проксируют" базовый!
Теперь это очень похоже на то, как Аспекты работают в Java! Аспекты сами по себе достаточно развиты с точки зрения их механизма и гибкости. Но, по сути, они делают следующее: возьмите метод "порекомендованный" (я говорю о весенней номенклатуре AOP и не уверен, применимо ли он также и к AspectJ), оберните вокруг них функциональность, а также предикаты и т.п., и прокси "рекомендованный" метод с обернутым.
Обратите внимание, что эти размышления на очень абстрактном и концептуальном уровне, чтобы помочь получить общую картину. Когда вы начнете углубляться в глубину, все эти концепции - декораторы, аннотации, аспекты - имеют довольно сложную область. Но на абстрактном уровне они очень сопоставимы.
TLDR
С точки зрения внешнего вида, python-декораторы можно считать похожими на аннотации Java, но под капотом они работают очень похоже на то, как работают аспекты в Java.
Ответ 3
Я использую оба из них аналогичным образом: чтобы включить/выключить параметры отладки или тестирования.
Например (декораторы 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 и т.д. могут выполнять похожие задания или более сложные.
Ответ 4
отказ от ответственности - Я не знаю Java
С этой точки зрения я предполагаю, что аннотация Java похожа на аннотацию python, представленную с PEP 3107. Аннотации - это способы привязки метаданных к самому объекту функции.
Декораторы (от PEP 0318) обычно предназначены для создания новых функций (хотя я полагаю, что декоратор мог бы вернуть и старую функцию, аннотирующую его), Эти новые функции обычно обтекают входную функцию, но они могут делать что угодно. Здесь глупый пример, в котором мы всегда передаем 'foo'
в качестве второго аргумента:
def second_always_foo(func):
def wrapper(*args,**kwargs):
args = list(args)
args[1] = 'foo'
return func(*args,**kwargs)
return wrapper
@second_always_foo
def printer(arg1,arg2):
print arg1,arg2
printer("Hello","world")
Обратите внимание, что этот пример можно было бы написать без декоратора как:
...
def printer(arg1,arg2):
print arg1,arg2
printer = second_always_foo(printer)
Ответ 5
Декораторы Python и аннотации Java имеют один и тот же синтаксис, но для двух совершенно разных целей! Они не совместимы или взаимозаменяемы никоим образом!
В недавнем проекте у меня была необходимость использовать семантику аннотации java в скрипте python, и я искал способ эмулировать его и нашел это:
В Python есть функция под названием "Docstring"!
Это не что иное, как специальная строка комментария, которая должна быть первой строкой в модуле, классе или функции!
Как и строка комментария, вы можете использовать любую форму текста. Но что делает его таким особенным для меня в этом случае, так это то, что он может быть прочитан инстроспекцией Python !!
Так что он может работать как аннотация 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
Очевидно, что недостатки заключаются в том, что вам приходится самостоятельно анализировать все метаданные, которые вы используете в своих "аннотациях, подобных java как python"!