我一直試圖從語言的角度來理解Flask裝飾器。基於我對裝飾器的理解,方法1,方法2和方法3應該具有相同的性質。擴展裝飾器後來手動崩潰程序
# server.py
#
# callback-based server response, based on official Flask docs:
# http://flask.pocoo.org/snippets/8/
#
# to run server:
# gunicorn server:app --bind localhost:5000
#
# to test:
# curl http://localhost:5000/1 -X POST -d POST_DATA -H "Content-Type: application/json"
# curl http://localhost:5000/2 -X POST -d POST_DATA -H "Content-Type: application/json"
# curl http://localhost:5000/3 -X POST -d POST_DATA -H "Content-Type: application/json"
from flask import Flask, request
app = Flask(__name__)
def callback(*args, **kwargs):
print "post_data=", request.data
return "RESPONSE\n", 200
def wrapper(f):
return callback
# method 1
@app.route('/1', methods=['POST'])
@wrapper
def method1():
pass
# method 2
@app.route("/2", methods=['POST'])
def method2():
return wrapper(method2)
# method 3
@app.route("/3", methods=['POST'])
def method3():
return callback
但是,當我運行3捲曲測試時,結果是不同的。在/ 1和/ 2的情況下,程序進行打印「post_data = POST_DATA」後不久崩潰:
post_data= POST_DATA
[2017-08-03 15:20:26,625] ERROR in app: Exception on /3 [POST]
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1615, in full_dispatch_request
return self.finalize_request(rv)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1630, in finalize_request
response = self.make_response(rv)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1740, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/wrappers.py", line 885, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "/usr/local/lib/python2.7/dist-packages/werkzeug/test.py", line 903, in run_wsgi_app
buffer.append(next(app_iter))
StopIteration
注意,它在燒瓶死後完全離開我app.route方法。
一些基本的研究表明,其他人都遇到過這種「StopIteration異常」的問題: https://github.com/getsentry/raven-python/issues/514 但不是在這樣一個簡單的例子,也沒有任何例如使用官方燒瓶文檔(http://flask.pocoo.org/snippets/8/)響應回調格局。所以我認爲這個問題不在Flask本身,而在於我對裝飾器的理解。
我不明白3種方法如何可能做不同的事情。他們都引用完全相同的「回調」功能。要麼他們成功地將這個功能提交給Flask,要麼他們沒有。
如果他們確實向Flask提供了該功能......那麼測試就會成功。 如果他們沒有將函數提供給Flask ...那麼Flask如何調用函數來打印「post_data = POST_DATA」?
這種行爲看起來完全不合邏輯。
(或者我誤解一個裝飾做什麼,它實際上是把某種隱藏的元數據到結果和瓶正被邪惡和檢查無證方式的元數據。)
不,方法1不調用回調。添加一個斷言回調,你會發現它不是從method1調用。 Flask在所有3種方法中調用回調函數。 –
總而言之,裝飾者正在做着讓Flask高興的東西,但它並沒有調用回調。該回調稍後將通過werkzeug/test模塊進行調用。 –
當然方法1正在調用回調。這就是它工作的原因,以及爲什麼當你訪問'/ 1'時你會看到'RESPONSE'。我建議刪除這些評論並將它們移到你的問題中,在那裏你可以格式化它們,使它們可讀。請注意,我並不是聲稱* decorator *正在調用'callback';請再看看這個答案(並注意這裏提供的代碼有效)。 – larsks