Python 烧瓶中的定制装饰器不工作?

Python 烧瓶中的定制装饰器不工作?,python,flask,decorator,Python,Flask,Decorator,我有以下代码: 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()

我有以下代码:

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 -
发生什么事了?为什么我的装修工不工作

编辑

我认为你们似乎看不出问题所在


当我有
@app.route
之前的
@track\u time\u花费的时间时,两种方法都返回条。这里的错误是调用localhost:8888/foo会导致http响应和打印函数中出现
bar

你为什么说你的装修工不工作

在第二个示例中,decorator正在运行,这样一个简单的函数可以在0.035毫秒内执行(3.5e-05表示3.5乘以10乘以-5的幂)


作为参考,您之所以需要颠倒两个decorator的顺序,是因为
app.route
注册了正在传递的函数


因此,您需要将修饰函数传递给它,从而传递命令。

Flask的
路由
函数是一个注册函数,从您调用它的副作用的意义上讲,它将为端点注册视图函数。但是,您只注册了视图函数,而不是装饰视图函数。只需切换装饰程序的顺序即可注册“时间跟踪”函数


此外,您还可以使用@app.before_request和@app.teardown_request-registed函数更可靠地跟踪时间(考虑到呈现模板等所需的时间)。

其他答案似乎缺失,当您切换装饰程序的顺序时,/foo会将“bar”作为响应。您必须在此处使用
@wrapps
,除非您手动更新
\uuuuuu name\uuuuuuuuu
\uuuuuuuuuu模块
等。Flask使用的方法有点像Singleton,并且将装饰器视为
wrapped()
方法,而不是实际包装的方法。因此,您的路由将不断被最后一个使用装饰器的方法覆盖

import datetime
from functools import wraps

from flask.app import Flask

app = Flask(__name__)
app.config.from_object(__name__)
app.debug = True


def track_time_spent(name):
    def decorator(f):
        @wraps(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"

app.run(host='0.0.0.0', port=8888)

“其他窗口”是什么意思?flask不使用您“直接”编写的函数对象,而是将其存储到底层的werkzeug基中,并根据请求调用它们。我声称我的装饰程序不起作用,因为访问/foo返回“bar”