我有以下代码:
import datetime
from flask.app import Flask
app = Flask(__name__)
app.config.from_object(__name__)
app.debug = True
def track_time_spent(name):
def decorator(f):
def wrapped(*args, **kwargs):
start = datetime.datetime.now()
ret = f(*args, **kwargs)
delta = datetime.datetime.now() - start
print name, "took", delta.total_seconds(), "seconds"
return ret
return wrapped
return decorator
@app.route('/foo')
@track_time_spent('foo')
def foo():
print "foo"
return "foo"
@app.route('/bar')
@track_time_spent('bar')
def bar():
print "bar"
return "bar"
我无法让foo返回“foo”:
$ curl localhost:8888/foo
bar
(flask window)
bar
bar took 8.2e-05 seconds
127.0.0.1 - - [18/Apr/2013 19:21:31] "GET /foo HTTP/1.1" 200 -
$ curl localhost:8888/bar
bar
(flask window)
bar
bar took 3.5e-05 seconds
127.0.0.1 - - [18/Apr/2013 19:21:35] "GET /bar HTTP/1.1" 200 -
怎么了?为什么我的装饰工不工作?
编辑
我觉得你们似乎看不出问题所在。
当我在@track_time_spent
之前有@app.route
时,两个方法都返回bar。这里的错误是调用localhost:8888/foo会在http响应和print函数中导致bar
。
其他的答案似乎没有,当您切换装饰器的顺序时,您从“/foo”得到的响应是“bar”。除非手动更新
__name__
、__module__
等,否则必须在此处使用@wraps
。Flask使用你的方法有点像singleton,把你的装饰器看作是wrapped()
方法,而不是你实际包装的方法。因此,使用decorator的最后一个方法将不断覆盖您的路由。Flask的
route
函数是一个注册函数,因为它的副作用是您调用它-它将为端点注册您的view函数。但是,您只注册view函数,而不是修饰的视图函数。只需切换decorators的顺序来注册“时间跟踪”函数。此外,您还可以使用@app.before廑request和@app.teardown廑request-registered函数更可靠地跟踪时间(考虑到呈现模板等所需的时间)。
你为什么说你的装修工不工作?
在第二个示例中,decorator正在运行,这样一个简单的函数将在0.035毫秒内执行是现实的(3.5e-05是一个表示法,表示3.5乘以10的幂为-5)。
作为参考,之所以需要颠倒两个decorator的顺序,是因为
app.route
注册了传递它的函数。因此,您需要将修饰函数传递给它,从而传递顺序。
相关问题 更多 >
编程相关推荐