web-dev-qa-db-fra.com

Est un Python Decorator identique à Java annotation, ou Java avec Aspects?)

Les décorateurs Python sont-ils identiques ou similaires, ou fondamentalement différents des annotations Java ou quelque chose comme Spring AOP ou Aspect J?)

44
bn.

Les décorateurs Python ne sont que du sucre syntaxique pour passer une fonction à une autre fonction et remplacer la première fonction par le résultat:

@decorator
def function():
    pass

est du sucre syntaxique pour

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

Les annotations Java en elles-mêmes stockent juste des métadonnées, vous devez avoir quelque chose qui les inspecte pour ajouter un comportement.

Les systèmes Java AOP sont des choses énormes construites sur Java, les décorateurs ne sont que la syntaxe du langage avec peu ou pas de sémantique attachée, vous ne pouvez pas vraiment les comparer.

57
Pavel Anossov

C'est une question très valable que n'importe qui peut essayer simultanément dans ces deux langues. J'ai passé du temps sur python moi-même, et je me suis récemment mis à niveau avec Java et voici mon point de vue sur cette comparaison).

Les annotations Java sont - juste cela: des annotations. Ce sont des marqueurs; des conteneurs de métadonnées supplémentaires sur l'objet sous-jacent qu'ils marquent/annotent. Leur simple présence ne modifie pas le flux d'exécution du sous-jacent, ou n'ajoute pas d'encapsulation/wrapper quelconque au-dessus du sous-jacent. Alors, comment aident-ils? Ils sont lus et traités par - Processeurs d'annotation. Les métadonnées qu'elles contiennent peuvent être utilisées par des processeurs d'annotation personnalisés pour ajouter des fonctionnalités auxiliaires qui facilitent la vie; MAIS, et encore une fois, ils ne modifient AUCUN flux d'exécution d'un sous-jacent, NOR enrouler autour d'eux.

L'emphase sur "ne pas modifier le flux d'exécution" sera claire pour quelqu'un qui a utilisé les décorateurs python. Python décorateurs, tout comme Java dans l'aspect et la convivialité sont très différentes sous le capot. Elles prennent le sous-jacent et s'enroulent autour de lui de quelque manière que ce soit, comme le souhaite l'utilisateur, évitant peut-être même complètement d'exécuter le sous-jacent lui-même, le cas échéant choisit de le faire. Ils prennent le sous-jacent, s'enroulent autour de lui et remplacent le sous-jacent par ceux qui sont enveloppés. Ils "procurent" effectivement le sous-jacent!

Maintenant que est assez similaire au fonctionnement d'Aspects en Java! Les aspects en soi sont assez évolués en termes de mécanisme et de flexibilité. Mais en gros, ce qu'ils font est de prendre la méthode `` conseillée '' (je parle dans la nomenclature AOP du printemps, et je ne sais pas si elle s'applique également à AspectJ), envelopper les fonctionnalités autour d'eux, ainsi que les prédicats et les goûts, et `` proxy 'la méthode' conseillée 'avec celle encapsulée.

Veuillez noter que ces réflexions sont à un niveau très abstrait et conceptuel, pour aider à obtenir une vue d'ensemble. Au fur et à mesure que vous commencez à approfondir, tous ces concepts - décorateurs, annotations, aspects - ont une portée assez complexe. Mais à un niveau abstrait, ils sont très comparables.

TLDR

En termes de look and feel, python décorateurs peuvent être considérés comme similaires à Java annotations, mais sous le capot, ils fonctionnent très très similaire à la façon dont les aspects fonctionnent) en Java.

14
Shreyas

J'utilise les deux de la même manière: pour activer/désactiver les options de débogage ou de test.

Par exemple (décorateurs 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):
    ...

Pour Java annotations, utilisez getAnnotation, etc. peut faire des tâches similaires ou plus compliquées.

2
鄭大大

Les décorateurs Python et Java Annotations partagent la même syntaxe mais à deux fins très différentes! Ils ne sont pas compatibles ou interchangeables pour aucune façon!

Sur un projet récent, j'ai eu la nécessité d'utiliser la sémantique d'annotation Java Java sur un script python, et j'ai cherché un moyen de l'émuler et j'ai trouvé ceci:

Dans Python il y a une fonctionnalité appelée 'Docstring'!

Ce n'est rien d'autre qu'une ligne de commentaire spéciale qui doit être la première ligne d'un module, d'une classe ou d'une fonction!

Comme une ligne de commentaire, vous pouvez utiliser n'importe quelle forme de texte. Mais ce qui me rend si spécial dans ce cas, c'est qu'il est lisible par python instrospection !!

Il peut donc fonctionner comme une annotation Java, qui a également besoin de la réflexion Java pour interpréter et réagir aux métadonnées qui en découlent !!)

Suivez un court exemple:

Source a.py

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

Source b.py (où je dois traiter @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

Évidemment, cet inconvénient est d'avoir à analyser par vous-même toutes les métadonnées que vous utilisez dans vos 'python Java comme des annotations'!

0
Júlio Oliveira