Python 装饰器与 Java 注释或 Java 与 Aspects 相同吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15347136/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is a Python Decorator the same as Java annotation, or Java with Aspects?
提问by bn.
Are Python Decorators the same or similar, or fundamentally different to Java annotations or something like Spring AOP, or Aspect J?
Python 装饰器与 Java 注释或 Spring AOP 或 Aspect J 之类的东西是否相同或相似,或根本不同?
回答by Pavel Anossov
Python decorators are just syntactic sugar for passing a function to another function and replacing the first function with the result:
Python 装饰器只是将函数传递给另一个函数并用结果替换第一个函数的语法糖:
@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 注释本身只存储元数据,您必须有一些东西来检查它们以添加行为。
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.
Java AOP 系统是构建在 Java 之上的巨大事物,装饰器只是语言语法,几乎没有附加语义,您无法真正比较它们。
回答by Shreyas
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.
这是一个非常有效的问题,任何同时涉足这两种语言的人都可以得到。我自己花了一些时间在 python 上,最近让自己跟上 Java 的速度,这是我对这个比较的看法。
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.
Java 注释是 - 只是:注释。它们是标记;关于他们正在标记/注释的基础对象的附加元数据的容器。它们的存在不会改变底层的执行流程,或者不会在底层之上添加某种封装/包装器。那么他们如何提供帮助呢?它们由 - 注释处理器读取和处理。它们包含的元数据可由自定义编写的注释处理器使用,以添加一些使生活更轻松的辅助功能;但是,再一次,它们既不会改变底层的执行流程,也不会环绕它们。
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!
对于使用过 python 装饰器的人来说,“不改变执行流程”的压力会很明显。Python 装饰器虽然在外观和感觉上类似于 Java 注释,但在幕后却大不相同。他们根据用户的需要,以任何方式将底层代码包裹起来,甚至可能完全避免运行底层代码本身,如果有人选择这样做的话。他们取下底层,将自己包裹起来,然后用包裹的替代底层。他们有效地“代理”了底层!
Now thatis 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.
现在这与 Aspects 在 Java 中的工作方式非常相似!就其机制和灵活性而言,方面本身已经有了很大的发展。但本质上,他们所做的是——采用“建议”方法(我说的是 spring AOP 命名法,不确定它是否也适用于 AspectJ),将功能以及谓词等包裹起来,然后“用包装的方法代理''建议'方法。
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
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.
在外观和感觉方面,python 装饰器可以被认为类似于 Java 注释,但在幕后,它们的工作方式与 Java 中的 Aspects 的工作方式非常相似。
回答by u5829541
I use both of them in a similar way: to turn on/off debugging or testing options.
我以类似的方式使用它们:打开/关闭调试或测试选项。
For example (Python decorators):
例如(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):
...
For Java annotations, use getAnnotation, etc.can do the similar jobs or more complicated ones.
对于 Java 注释,使用getAnnotation 等可以完成类似或更复杂的工作。
回答by Júlio Oliveira
Python decorators and Java Annotations share de same syntax but to two very different purposes! They aren't compatible or interchangeable for none way!
Python 装饰器和 Java 注释共享相同的语法,但有两个截然不同的目的!它们绝对不兼容或不可互换!
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:
在最近的一个项目中,我有必要在 python 脚本上使用 java 注释语义,我搜索了一种方法来模拟它并找到了这个:
In Python there are a functionality called 'Docstring'!
在 Python 中有一个名为“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!!
与注释行一样,您可以使用任何形式的文本。但是在这种情况下对我来说如此特别的是它可以通过 python 内省读取!!
So it can works like a Java Annotation, that too needs the Java reflection to interpret and react to metadata carryed from it!!
所以它可以像 Java Annotation 一样工作,也需要 Java 反射来解释和响应从中携带的元数据!!
Follow a short example:
看一个简短的例子:
Source a.py
源 a.py
```
def some_function():
'''@myJavaLikeAnnotation()'''
... (my function code) ...
```
Source b.py (where I have to process the @myJavaLikeAnnotacion()):
源 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
Obviously that disadvantages is to have to parse by yourself all the metadata that you use in your 'python java like annotations'!
显然,缺点是必须自己解析在“python java like annotations”中使用的所有元数据!