61

Python 装饰器与 Java 注释或诸如 Spring AOP 或 Aspect J 之类的东西是否相同或相似,或根本不同?

4

4 回答 4

71

Python 装饰器只是将一个函数传递给另一个函数并用结果替换第一个函数的语法糖:

@decorator
def function():
    pass

是语法糖

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

Java 注释本身只存储元数据,您必须有一些东西来检查它们以添加行为。

 

Java AOP 系统是建立在 Java 之上的巨大的东西,装饰器只是语言语法,几乎没有附加语义,你无法真正比​​较它们。

于 2013-03-11T19:46:32.423 回答
28

这是一个非常有效的问题,任何同时涉足这两种语言的人都可以得到。我自己花了一些时间在 python 上,最近一直在让自己跟上 Java 的速度,这是我对这个比较的看法。

Java 注释就是——就是这样:注释。它们是标记;关于它们正在标记/注释的底层对象的附加元数据的容器。它们的存在不会改变底层的执行流程,或者不会在底层之上添加某种封装/包装器。那么他们如何提供帮助呢?它们由注释处理器读取和处理。它们包含的元数据可以被定制编写的注释处理器用来添加一些辅助功能,使生活更轻松;但是,同样,它们既不会改变底层的执行流程,也不会环绕它们。

对于使用过 python 装饰器的人来说,“不改变执行流程”的压力是显而易见的。Python 装饰器虽然在外观和感觉上类似于 Java 注释,但在底层却大不相同。他们采用底层证券并根据用户的需要以任何方式将其包裹起来,如果有人选择这样做,甚至可能完全避免运行底层证券本身。他们拿走底层证券,将自己包裹起来,然后用被包裹的底层证券替换底层证券。他们有效地“代理”了底层证券!

现在与 Aspects 在 Java 中的工作方式非常相似!就其机制和灵活性而言,各个方面本身已经相当进化。但从本质上讲,他们所做的是 - 采用“建议”方法(我说的是 spring AOP 命名法,不确定它是否也适用于 AspectJ),将功能与谓词等一起包装在它们周围,并且'用包装的方法代理'建议的'方法。

请注意,这些思考处于非常抽象和概念的层面,以帮助了解全局。当你开始深入研究时,所有这些概念——装饰器、注释、方面——都有相当大的涉及范围。但在抽象层面上,它们是非常可比的。

TLDR

在外观方面,python 装饰器可以被认为类似于 Java 注释,但在底层,它们的工作方式与 Java 中 Aspects 的工作方式非常相似。

于 2018-03-19T06:06:47.087 回答
2

我以类似的方式使用它们:打开/关闭调试或测试选项。

例如(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 等可以完成类似的工作或更复杂的工作。

于 2017-11-22T06:00:03.207 回答
0

Python 装饰器和 Java 注释共享相同的语法,但有两个非常不同的目的!它们是不兼容或不可互换的!

在最近的一个项目中,我有必要在 python 脚本上使用 java 注释语义,我搜索了一种模拟它的方法并发现了这个:

在 Python 中有一个称为“Docstring”的功能!

它只不过是一个特殊的注释行,它必须是模块、类或函数的第一行!

就像注释行一样,您可以使用任何形式的文本。但在这种情况下,它对我来说如此特别的是它可以被 python 自省读取!

所以它可以像 Java Annotation 一样工作,也需要 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

显然,缺点是必须自己解析在“python java like annotations”中使用的所有元数据!

于 2019-09-01T16:45:08.987 回答