@decorator语法只是语法糖,因此两个示例都具有相同的行为.这也意味着你们之间所做的任何区别都可能没有你想象的那么有意义.
虽然,您可以使用inspect来读取脚本并查看如何在上面的框架中调用装饰器.
import inspect
def decorate(func):
# See explanation below
lines = inspect.stack(context=2)[1].code_context
decorated = any(line.startswith('@') for line in lines)
print(func.__name__, 'was decorated with "@decorate":', decorated)
return func
请注意,我们必须为inspect.stack函数指定context = 2. context参数指示必须返回当前行周围的代码行数.在某些特定情况下,例如在装饰子类时,当前行是在类声明而不是装饰器上. The exact reason for this behaviour has been explored here.
例
@decorate
def bar():
pass
def foo():
pass
foo = decorate(foo)
@decorate
class MyDict(dict):
pass
产量
bar was decorated with "@decorate": True
foo was decorated with "@decorate": False
MyDict was decorated with "@decorate": True
警告
还有一些我们难以克服的极端情况,例如装饰器和类声明之间的换行符.
# This will fail
@decorate
class MyDict(dict):
pass