Подтвердить что ты не робот

Является ли Python Decorator таким же, как аннотация Java, или Java с аспектами?

Декораторы Python одинаковы или похожи или принципиально отличаются от аннотаций Java или что-то вроде Spring AOP или Aspect J?

4b9b3361

Ответ 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"!