说我有一个装饰工厂工厂。它是无用的,只是累积参数,并添加到结果中,但仅作为一个例子:
def decorator_factory_factory(a):
def decorator_factory(b):
def decorator(f):
def decorated(*args, **kwargs):
return f(*args, **kwargs) + a + b
return decorated
return decorator
return decorator_factory
我试着像这样使用它:
@decorator_factory_factory(3)(1)
def should_return_5():
return 1
我得到一个SyntaxError。当然它应该允许任意Python表达式作为装饰器?
我也尝试过:
@(decorator_factory_factory(3)(1))
def should_not_be_touched():
return 1
但这是另一个SyntaxError。
我做错了吗?我找到的唯一方法是:
_decorator_factory = decorator_factory_factory(3)
@_decorator_factory(1)
def should_not_be_touched():
return 1
del _decorator_factory
但这需要另外一个需要删除的变量
答案 0 :(得分:1)
修饰器语法is restricted。您不允许使用任意表达式。允许您使用.
运算符,最后最多只能使用一个调用()
,因此
@decorator_factory_factory(3)(1)
def should_return_5():
return 1
是语法错误,因为它的调用(3)
不在结尾。
实际上,这不是限制,因为装饰器只是函数声明后的赋值糖。您可以不受限制地自己做
def should_return_5():
return 1
should_return_5 = decorator_factory_factory(3)(1)(should_return_5)
不会创建需要删除的其他变量。
此外,单个函数调用就足以通过一个简单的标识函数潜入任意表达式。
def identity(x):
return x
@identity(decorator_factory_factory(3)(1))
def should_return_5():
return 1
使用identity
的短名称(不是id
,这是内置的),这与您想要的@(decorator_factory_factory(3)(1))
语法非常接近。
答案 1 :(得分:0)
该函数是在错误的包装器上发送的,从未调用
def decorator_factory_factory():
def decorator_factory(f):
def decorator():
return f()
return decorator
return decorator_factory
@decorator_factory_factory()
def should_not_be_touched():
return 1