我对Python相当陌生,并且一直在学习装饰师。在使用了Flask之后,我试图编写一些代码来模拟它们的路由处理程序/装饰器,只是为了了解装饰器(带有参数)是如何工作的。
在下面的代码中,当脚本运行时,路由修饰器似乎会调用自己。我的问题是,当我运行这个脚本时,app.route()怎么可能被调用,这里到底发生了什么?注意,我没有在任何地方直接调用我的index()函数。
# test.py
class Flask(object):
def __init__(self, name):
self.scriptname = name
def route(self, *rargs, **kargs):
args = list(rargs)
if kargs:
print(kargs['methods'])
def decorator(f):
f(args[0])
return decorator
app = Flask(__name__)
@app.route("/", methods = ["GET","PUT"])
def index(rt):
print('route: ' + rt)上面在我的终端上打印了这个:
$ python test.py
['GET', 'PUT']
route: /任何洞察力都将不胜感激。
发布于 2013-09-30 20:30:25
@app.route("/", methods = ["GET","PUT"])是一个可执行语句:它调用app对象的route()方法。因为它位于模块级别,所以在导入脚本时将执行它。
现在,调用app.route(...)的结果是一个函数,因为您已经使用@将其标记为一个装饰符,因此该函数将包装index。请注意,语法只是这方面的一个快捷方式:
index = app.route(...)(index)换句话说,Python将调用app.route()以index作为参数返回的函数,并将结果存储为新的index函数。
然而,你在这里错过了一个层次。一个普通的装潢师,没有平面语,是这样写的:
@foo
def bar()
pass在导入模块时,运行foo()并返回一个包装bar的函数。但是在装饰器调用中调用您的route()函数!因此,实际上您的函数需要返回一个装饰函数,该函数本身返回一个包装原始函数的函数.当然是挠头了。
您的route方法应该更像这样:
def route(self, *rargs, **kargs):
args = list(rargs)
if kargs:
print(kargs['methods'])
def decorator(f):
def wrapped(index_args):
f(args[0])
return wrapped
return decorator发布于 2013-09-30 20:18:58
基本上..。app.route(index, "/", ["GET", "PUT"])是一个函数。这是要调用的函数,而不是索引。
在代码中,当调用index()时,它调用app.route(index, "/", ["GET", "PUT"])。首先打印kargs['methods'],然后创建装饰器函数:
def decorator(f):
f(args[0])这个装饰器将用一个参数args[0]调用修饰函数(args[0]),这里的参数是"/“。这个打印route: /。
我发现的装饰师最好的解释是:How to make a chain of function decorators?
如果你不想自燃,你可以用这样的方式定义你的装饰者:
def route(*rargs, **kargs):
args = list(rargs)
if kargs:
print(kargs['methods'])
def decorator(f):
f(args[0])
return decorator
@app.route("/", methods = ["GET","PUT"])
def index(rt):
print('route: ' + rt)但是,索引的rt参数将永远不会被使用,因为route总是用args[0]调用index,而args[0]总是\.
https://stackoverflow.com/questions/19102930
复制相似问题