2015-12-07 56 views
0

我寫了一個簡單的燒瓶應用程序,它爲用戶返回指定的ID。我想讓每條路線都使用相同的邏輯,所以我想將其作爲裝飾者來實現。燒瓶路線裝飾運行時錯誤

# the decorator 
def session_decorator(data_handle_func): 
    session_id = request.cookies.get('static') 
    if session_id is None: 
     session_id = uuid.uuid1().hex 
    resp = make_response(data_handle_func(session_id)) 
    resp.set_cookie('static', session_id) 
    return resp 

# version 1 
@app.route("/session") 
def sessionx(): 
    def simple(session_id): 
     return session_id 
    return session_decorator(simple) 

# version 2, throw excetion 
@app.route("/session2") 
@session_decorator 
def sessionx(session_id): 
    return session_id 

第一個版本正常工作。第二個是需要的版本,它拋出:

Traceback (most recent call last): 
    File "app.py", line 466, in <module> 
    @session_decorator 
    File "app.py", line 451, in session_decorator 
    session_id = request.cookies.get('static') 
    File "/home/users/install/python/lib/python2.7/site-packages/Werkzeug-0.11-py2.7.egg/werkzeug/local.py", line 342, in __getattr__ 
    return getattr(self._get_current_object(), name) 
    File "/home/users/install/python/lib/python2.7/site-packages/Werkzeug-0.11-py2.7.egg/werkzeug/local.py", line 301, in _get_current_object 
    return self.__local() 
    File "/home/users/install/python/lib/python2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/globals.py", line 20, in _lookup_req_object 
    raise RuntimeError('working outside of request context') 
RuntimeError: working outside of request context 

UPDATE

根據這一related question,我寫了下面的裝飾,它的工作原理。但是我不知道爲什麼這會起作用,並且實際上導致RuntimeError在這裏?任何人都可以提出一些建議嗎?

def session_decorator_v2(data_handle_func): 
    @functools.wraps(data_handle_func) 
    def decorated_function(*args, **kws): 
     session_id = request.cookies.get('static') 
     if session_id is None: 
      print "not exist" 
      session_id = uuid.uuid1().hex 
     resp = make_response(data_handle_func(session_id)) 
     resp.set_cookie('static', session_id) 
     return resp 
    return decorated_function 
+0

@KevinGuan我的問題是不是'UT'。 @rmn我會嘗試一下,一旦有效,我會解決這個問題。 – luoluo

+0

啊,夠公平的。撤回了我的投票。 –

回答

1

你的裝飾器是錯誤定義的。它必須是一個函數返回將要執行的功能,並呼籲data_handle_func

# the decorator 
def session_decorator(data_handle_func): 
    def session_parser(): 
     session_id = request.cookies.get('static') 
     if session_id is None: 
      session_id = uuid.uuid1().hex 
     resp = make_response(data_handle_func(session_id)) 
     resp.set_cookie('static', session_id) 
     return resp 
    return session_parser 

# version 2, throw excetion 
@app.route("/session2") 
@session_decorator 
def sessionx(session_id): 
    return session_id 

您看到了這個錯誤的原因是因爲你的「裝飾」是隻要連接到路由執行。當你做request.cookies.get('static')瓶哭是因爲它沒有一個請求上下文,但(你初始化應用程序,不處理的請求)在OP的更新

編輯: 您提供的代碼是完全一樣的是我給了你。

@functools.wraps(data_handle_func) 

是一個裝飾器,它將函數名和描述放到包裝函數中。所以裝飾者在使用時不會改變丟失描述的名字。

裝飾器基本上只是一個功能,當某個函數會返回一個函數...

+0

非常感謝。你的意思是在初始化應用程序時執行了錯誤的裝飾器,應該在處理請求時執行該裝飾器。這導致了錯誤? – luoluo

+0

是的,裝飾器只返回一個函數,它將替換你正在裝飾的函數。裝飾器只執行一次,但每次訪問裝飾函數時都會執行內部函數。 – Cyrbil

+0

請求上下文之外的'RuntimeError是否意味着上下文不存在,並且在處理上下文時只會在這裏? – luoluo