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

dis*_*dng 5 python decorator flask

我有以下代码:

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"
Run Code Online (Sandbox Code Playgroud)

我无法让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 -
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?我的装饰师为什么不工作?

编辑

我认为你们似乎无法看到问题.

当我有@app.route之前@track_time_spent,两种方法都返回吧.这里的错误是调用localhost:8888/foo导致barhttp响应和print函数.

TkT*_*ech 16

其他答案似乎缺少,当你切换装饰器的顺序时,你得到"bar"作为"/ foo"的响应.@wraps除非您手动更新__name__,等__module__,否则必须使用此处.Flask使用你的方法有点像单身,并且看你的装饰器就像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)
Run Code Online (Sandbox Code Playgroud)