def decorator(fn):
def wrapper(*args, **kwargs):
print 'With sour cream and chives!',
return fn(*args, **kwargs)
return wrapper
class Potato(object):
def __call__(self):
print 'Potato @ {} called'.format(id(self))
spud = Potato()
fancy_spud = decorator(Potato())
通过这段代码,我们有两个可调用类的实例,一个是修饰的,一个是普通的:
>>> spud()
Potato @ 140408136280592 called
>>> fancy_spud()
With sour cream and chives! Potato @ 140408134310864 called
我想知道是否支持在仅一个实例的可调用对象上使用 @decorator
语法,而不是装饰类/方法,后者适用于每个实例。根据this流行的答案,@syntax 只是糖分:
function = decorator(function)
但这是否过于简单化了?在我所有半生不熟的尝试中,它似乎只在语法出现在 def
、class
、空格或 @another_decorator
之前时才有效。
@decorator
baked = Potato()
这是一个SyntaxError
。
baked = Potato()
@decorator
baked
还有语法错误
。
@decorator
def baked(_spud=Potato()):
return _spud()
有效,但丑陋且有点作弊。
最佳答案
是的,这是过于简单化了。如果我们看the grammar , decorator
仅出现在规则 decorators
中,它仅作为 classdef
或 funcdef
的一部分出现:
decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
decorators: decorator+
decorated: decorators (classdef | funcdef)
什么 language reference says (我认为这是链接答案中重复的内容)是
@f1(arg)
@f2
def func(): pass
相当于
def func(): pass
func = f1(arg)(f2(func))
类定义也类似。但这并不意味着可以在任何地方应用 @decorator
语法;它仅在函数或类定义之前有效。
顺便说一句,即使是官方文档也不是严格正确的;在调用装饰器时,函数(或类)未绑定(bind)到封闭的命名空间或范围,因此给定的语法并不完全等同。
def
和 class
语句有一些有趣的地方,我认为这是它们是 @decorator< 唯一支持的语句的部分原因
语法:它们是 Python 中将名称绑定(bind)到知道该名称是什么的对象的唯一方法。
最后,这是调用您可能喜欢的装饰器的另一种方法:
@decorator
class baked:
__metaclass__ = lambda *_: Potato()
关于python - 如何装饰可调用类的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24122444/