Is a Python Decorator the same as Java annotation, or Java with Aspects?

Question:

Are Python Decorators the same or similar, or fundamentally different to Java annotations or something like Spring AOP, or Aspect J?

Asked By: bn.

||

Answers:

Python decorators are just syntactic sugar for passing a function to another function and replacing the first function with the result:

@decorator
def function():
    pass

is syntactic sugar for

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

Java annotations by themselves just store metadata, you must have something that inspects them to add behaviour.

 

Java AOP systems are huge things built on top of Java, decorators are just language syntax with little to no semantics attached, you can’t really compare them.

Answered By: Pavel Anossov

I use both of them in a similar way: to turn on/off debugging or testing options.

For example (Python decorators):

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):
    ...

For Java annotations, use getAnnotation, etc. can do the similar jobs or more complicated ones.

Answered By: 鄭大大

This is a very valid question that anyone dabbling in both these languages simultaneously, can get. I have spent some time on python myself, and have recently been getting myself up to speed with Java and here’s my take on this comparison.

Java annotations are – just that: annotations. They are markers; containers of additional metadata about the underlying object they are marking/annotating. Their mere presence doesn’t change execution flow of the underlying, or doesn’t add encapsulation/wrapper of some sort on top of the underlying. So how do they help? They are read and processed by – Annotation Processors. The metadata they contain can be used by custom-written annotation processors to add some auxiliary functionality that makes lives easier; BUT, and again, they NEITHER alter execution flow of an underlying, NOR wrap around them.

The stress on “not altering execution flow” will be clear to someone who has used python decorators. Python decorators, while being similar to Java annotations in look and feel, are quite different under the hood. They take the underlying and wrap themselves around it in any which way, as desired by the user, possibly even completely avoiding running the underlying itself as well, if one chooses to do so. They take the underlying, wrap themselves around it, and replace the underlying with the wrapped ones. They are effectively ‘proxying’ the underlying!

Now that is quite similar to how Aspects work in Java! Aspects per se are quite evolved in terms of their mechanism and flexibility. But in essence what they do is – take the ‘advised’ method (I am talking in spring AOP nomenclature, and not sure if it applies to AspectJ as well), wrap functionality around them, along with the predicates and the likes, and ‘proxy’ the ‘advised’ method with the wrapped one.

Please note these musings are at a very abstract and conceptual level, to help get the big picture. As you start delving deeper, all these concepts – decorators, annotations, aspects – have quite an involving scope. But at an abstract level, they are very much comparable.

TLDR

In terms of look and feel, python decorators can be considered similar to Java annotations, but under the hood, they work very very similar to the way Aspects work in Java.

Answered By: Shreyas

Python decorators and Java Annotations share de same syntax but to two very different purposes! They aren’t compatible or interchangeable for none way!

On a recent project, I had the necessity to use the java annotation semantics on a python script, and I searched a way to emulate it and found this:

In Python there are a functionality called ‘Docstring’!

It nothing more else than a special comment line that have to be the first line in a module, class or function!

Like a comment line, you can use any form of text. But what make it so special to me in this case is that is readable by python instrospection!!

So it can works like a Java Annotation, that too needs the Java reflection to interpret and react to metadata carryed from it!!

Follow a short example:

Source a.py

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

Source b.py (where I have to process the @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

Obviously that disadvantages is to have to parse by yourself all the metadata that you use in your ‘python java like annotations’!

Answered By: Júlio Oliveira