10

次のFlaskルートとカスタムヘルパーがあります。

from spots import app, db
from flask import Response
import simplejson as json


def json_response(action_func):
    def create_json_response(*args, **kwargs):
        ret = action_func(*args, **kwargs)
        code = 200
        if len(ret) == 2:
            code = ret[0]
            resp = ret[1]
        else:
            resp = ret[0]
        return Response(
            response=json.dumps(resp, indent=4),
            status=code,
            content_type='application/json'
        )

    return create_json_response


@app.route('/test')
@json_response
def test():
    return 400, dict(result="Test success")


@app.route('/')
@json_response
def home():
    return 200, dict(result="Home success")

/ testへのGETリクエストが次のようなものを返すことを期待します{"result":"Test success"}が、そうではありません。代わりに、すべてのリクエストが最後のルートと一致しているようhomeです。なんで?

これは、へのさまざまな呼び出しの間の絶縁の欠如が原因であるのだろうjson_responseか?

前もって感謝します。

4

1 に答える 1

14

Видул Петров が言ったように、解決策はfunctools.wrapsを使用することです:

import functools
def json_response(action_func):
    @functools.wraps(action_func)
    def create_json_response(*args, **kwargs):
        ...
return create_json_response

その理由は、Flask のルーティング システムが URL を「エンドポイント」にマップし、次にエンドポイントをビュー関数にマップするためです。エンドポイントのデフォルト__name__はビュー関数の属性です。この場合、装飾された関数が渡されたapp.routeため、エンドポイントはcreate_json_response両方のルール用であり、そのエンドポイントに対して定義された最後のビューが両方のケースで使用されました。

functools.wraps は__name__元の関数から (およびその他の属性) を取得し、これを修正します。装飾されたラッパーで使用することは常に良い考えです.

于 2012-07-27T10:50:08.143 に答える