[英]How can I decorate an instance of a callable class?
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
使用@decorator
语法 - 而不是装饰适用于每个实例的类/方法。 根据这个流行的答案,@syntax只是糖:
function = decorator(function)
但这是一种过度简化吗? 我的所有半生不熟的尝试似乎只有在def
, class
,whitespace或@another_decorator
之前出现语法时才能工作。
@decorator
baked = Potato()
这是一个SyntaxError
。
baked = Potato()
@decorator
baked
还有SyntaxError
。
@decorator
def baked(_spud=Potato()):
return _spud()
工作,但丑陋和有点作弊。
是的,这是过于简单化了。 如果我们查看语法 , decorator
只出现在规则decorators
,它只出现在classdef
或funcdef
一部分中:
decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
decorators: decorator+
decorated: decorators (classdef | funcdef)
语言参考说的是什么(我认为这是在链接答案中重复的内容)
@f1(arg)
@f2
def func(): pass
相当于
def func(): pass
func = f1(arg)(f2(func))
类似于类定义。 但这并不意味着@decorator
语法可以应用于任何地方; 它仅在函数或类定义之前立即生效。
顺便说一下,即使官方文件也不严格正确; 在调用decorator时,函数(或类)没有绑定到封闭的命名空间或范围中,因此给定的语法并不完全等效。
def
和class
语句有一些有趣的东西,我认为这是它们是@decorator
语法支持的唯一语句的部分原因:它们是Python中将名称绑定到知道什么的对象的唯一方法名字是 。
最后,这是调用您可能喜欢的装饰器的另一种方法:
@decorator
class baked:
__metaclass__ = lambda *_: Potato()
你质疑:
根据这个流行的答案,@syntax只是糖:
function = decorator(function)
但是,这样说更准确
@decorator
def function():
pass
语法糖是:
def function():
pass
function = decorator(function)
装饰器专门用于装饰函数,方法或类定义 。 引入类装饰器的PEP描述了语法:
decorated: decorators (classdef | funcdef)
funcdef: 'def' NAME parameters ['->' test] ':' suite
如您所见,装饰器必须紧跟在classdef
或funcdef
之前,因此无法直接在可调用类的实例上使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.