Python是否允许调用decorator工厂?
对,他有一个。在这篇文章中,他举了一个例子:Python是否允许调用decorator工厂?,python,grammar,Python,Grammar,对,他有一个。在这篇文章中,他举了一个例子: def decorator_factory_factory(method): def decorator_factory(regex): def decorator(f): def inner(*args, **kwargs): # do stuff with f(*args, **kwargs) # and method and rege
def decorator_factory_factory(method):
def decorator_factory(regex):
def decorator(f):
def inner(*args, **kwargs):
# do stuff with f(*args, **kwargs)
# and method and regex
return inner
return decorator
return decorator_factory
然后,他举了一个例子,说明如何给装饰师打电话:
@decorator_factory_factory('GET')('^/.*$')
def onGetAnything(self):
pass
这引起了我的注意。我以前从未尝试过调用decorator decorator工厂,因此我决定查看代码的行为:
>>> def decorator_factory_factory(method):
def decorator_factory(regex):
def decorator(f):
def inner(*args, **kwargs):
print(args, kwargs)
return inner
return decorator
return decorator_factory
>>> @decorator_factory_factory('GET')('^/.*$')
def onGetAnything(self):
pass
SyntaxError: invalid syntax
>>>
从上面可以看到,Python引发了一个SyntaxError
。为什么呢?除了显然为麦克拉肯先生工作的代码外,这类代码似乎应该运行得很好。它的语法是否与将函数调用链接在一起的语法基本相同?例如:
>>> def foo():
def bar():
return 2
return bar
>>> foo()()
2
>>>
我想他可能使用的是一个较旧的Python版本,允许使用这种语法,所以我查看了Python版本的语法,他在2009年写这篇文章时可能使用的语法;2.6.9. 但似乎仍然不允许链式装饰调用:
在任何Python版本中都允许使用这种语法吗。如果没有,那么伊恩是如何运行他的代码的呢?他只是犯了一个错误吗?作为一种解决方法,要让它正常工作,你可以让一个
装饰者\u调用者
装饰者,为你打电话:
def decorator_caller(decorator, args_list):
d = decorator
for args in args_list:
d = d(*args)
return d
这样使用:
@decorator_caller(decorator_factory_factory, (('GET',), ('^/.*$',)))
def onGetAnything(self):
pass
或者改用列表(因为单项元组看起来很混乱):
请注意,我不认为这样一个工厂是一个有用的东西来建立。当外部工厂真的会影响内部工厂的逻辑时,工厂工厂是有意义的。如果您所做的只是创建一个临时工厂来创建单个项目,只是为了立即扔掉该工厂,那么除了更复杂和更差的总体性能之外,您实际上什么也得不到 如果您实际将工厂存储在周围以供重用,则这将是另一回事:
getFactory = decorator_factory_factory('GET')
@getFactory('^/index.*$')
def index():
pass
@getFactory('^/.*$')
def x():
pass
这很有意义,语法也很好。但是,如果您只是想通过链接工厂调用来添加另一个参数来配置装饰器,那么您应该调整工厂以同时使用这两个参数。几乎可以肯定,这只是shell缩进函数定义。改为在文件中执行此操作。@DanielRoseman不。我不认为文章中提供的例子是有效的。decorator工厂可以用来生成decorator
GET=decorator\u factory\u factory('GET')
->@GET('regex')
,但我认为不可能按照作者描述的方式使用decorator。可能是误导。我很乐意出错并得到详细的解释,但它看起来不像是开箱即用的python行为。@Taras“我很乐意出错并得到详细的解释”——你和我都是。虽然我开始认为你是对的,而伊恩只是犯了个错误。我怀疑最初的博主是否真的尝试过。他写道(缩短):“我本可以使用这个函数……它完全不可读,所以划清界限……”谢谢你的回答。你的权利,你必须把工厂储存起来。我真的只是想知道这是否可能。但我猜答案似乎是“不”,因为我所研究的所有Python版本语法都会拒绝这种语法。甚至早在2.4版本。
@decorator_caller(decorator_factory_factory, (['GET'], ['^/.*$']))
def onGetAnything(self):
pass
getFactory = decorator_factory_factory('GET')
@getFactory('^/index.*$')
def index():
pass
@getFactory('^/.*$')
def x():
pass