假设我有一个装饰工厂工厂。这是非常无用的,仅累加参数并添加到结果中,仅作为示例:
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
但这需要一个附加变量,需要将其删除
最佳答案
更新:从Python 3.9开始,这不再是语法错误。参见PEP 614。
装饰器语法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))
语法非常接近。关于python - 为什么使用装饰器工厂工厂函数会出现语法错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44358027/