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

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

3 ответа

Решение

Декораторы Python являются просто синтаксическим сахаром для передачи функции другой функции и замены первой функции результатом:

@decorator
def function():
    pass

является синтаксическим сахаром для

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

Сами по себе аннотации Java просто хранят метаданные, у вас должно быть что-то, что проверяет их, чтобы добавить поведение.

Java AOP-системы - это огромные вещи, построенные на основе Java, декораторы - это просто синтаксис языка с практически не привязанной семантикой, вы не можете их реально сравнить.

Это очень актуальный вопрос, который может получить любой, кто балуется обоими этими языками одновременно. Я провел некоторое время на python и недавно освоил Java, и вот мое сравнение.

Java-аннотации - это просто аннотации. Это маркеры; контейнеры дополнительных метаданных о базовом объекте, который они помечают / аннотируют. Их простое присутствие не меняет поток выполнения базового объекта или не добавляет инкапсуляцию / оболочку какого-либо вида поверх базового. Так как они помогают? Они читаются и обрабатываются обработчиками аннотаций. Содержащиеся в них метаданные могут использоваться обработчиками пользовательских аннотаций для добавления некоторых дополнительных функций, облегчающих жизнь; НО, и опять же, они НИКОГДА не изменяют поток выполнения базового, NOR обтекания вокруг них.

Упор на "не изменяющийся поток выполнения" будет понятен тому, кто использовал декораторы Python. Декораторы Python, хотя и похожи на Java-аннотации по внешнему виду, совсем другие. Они берут базовый инструмент и оборачиваются вокруг него любым способом, по желанию пользователя, возможно, даже полностью избегая запуска самого базового пакета, если кто-либо решит это сделать. Они берут основу, оборачиваются вокруг нее и заменяют основу на завернутые. Они эффективно "проксируют" базовое!

Теперь это очень похоже на то, как Аспекты работают в Java! Сами по себе аспекты достаточно развиты с точки зрения их механизма и гибкости. Но, по сути, они делают следующее: возьмите метод "порекомендованный" (я говорю о весенней номенклатуре AOP, и не уверен, относится ли он также и к AspectJ), оберните вокруг них функциональность, а также предикаты и т.п., и прокси "рекомендованный" метод с обернутым.

Обратите внимание, что эти размышления на очень абстрактном и концептуальном уровне, чтобы помочь получить общую картину. Когда вы начнете углубляться в глубину, все эти концепции - декораторы, аннотации, аспекты - имеют довольно сложную область. Но на абстрактном уровне они очень сопоставимы.

TLDR

С точки зрения внешнего вида, python-декораторы можно считать похожими на аннотации Java, но под капотом они работают очень похоже на то, как работают аспекты в Java.

Я использую их обоих одинаково: для включения / выключения параметров отладки или тестирования.

Например (декораторы 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 и т. Д. Можно выполнять аналогичные или более сложные задачи.

Декораторы Python и аннотации Java используют один и тот же синтаксис, но для двух очень разных целей! Они ни в коем случае не совместимы и не взаимозаменяемы!

В недавнем проекте у меня возникла необходимость использовать семантику аннотации java в скрипте Python, и я искал способ подражать этому и нашел следующее:

В Python есть функция под названием "Строка документации"!

Это не что иное, как специальная строка комментария, которая должна быть первой строкой в ​​модуле, классе или функции!

Как и строка комментария, вы можете использовать любую форму текста. Но что делает его таким особенным в этом случае, так это то, что он читается с помощью инстроспекции 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"!

Другие вопросы по тегам