6

次のコードがあります。

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.routebeforeがある場合@track_time_spent両方のメソッドがバーを返します。ここでのエラーは、localhost:8888/foo を呼び出すとbar、http 応答と print 関数の両方が返されることです。

4

3 に答える 3

17

デコレータの順序を切り替えると、「/ foo」からの応答として「バー」が返されるという他の回答が欠落しているようです。、などを手動で@wraps更新しない限り、ここで使用する必要があります。Flask はメソッドをシングルトンのように使用し、実際にラップしたメソッドではなく、デコレーターをメソッドとして認識します。したがって、ルートはデコレータを使用する最後のメソッドによって上書きされ続けます。__name____module__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)
于 2013-04-19T02:42:00.097 に答える
0

デコレータが機能していないと言っているのはなぜですか?

2 番目の例では、デコレータが実行されており、このような単純な関数が 0.035 ミリ秒で実行されるのは現実的です (3.5e-05 は、10 の 3.5 乗 -5 を意味する表記法です)。


参考までに、2 つのデコレーターの順序を逆にする必要があった理由はapp.route、渡される関数を登録するためです。

したがって、装飾された関数、したがって順序を渡す必要があります。

于 2013-04-19T02:28:50.770 に答える