为什么这些装饰者从最外层到最里面调用,而不是相反?

时间:2014-03-10 19:07:08

标签: python tornado

我在tornado.websocket.WebSocketHandler子类中有以下方法:

@authenticate_user_async
@gen.coroutine
def on_message(self, data):
    """
    Callback when new message received via the socket.
    """
    # do stuff...

@authenticate_user_async装饰器如下:

def authenticate_user_async(f):
    """
    Authentication decorator based on http://tornadogists.org/5251927/

    Authenticates the user's credentials and sets self.current_user if valid
    """
    @functools.wraps(f)
    @gen.coroutine
    def wrapper(self, *args, **kwargs):
        # do stuff...

        f(self, *args, **kwargs)

    return wrapper

我认为最里面的装饰器首先被调用,所以预计需要它们被提供:

@gen.coroutine
@authenticate_user_async
def on_message(self, data):
   ...

但只有第一个版本有效且如果yield关键字位于on_message()方法内,则永远不会调用上面的版本。

为什么有必要使用第一个版本而不是第二个版本?

1 个答案:

答案 0 :(得分:0)

(我想我在回答你之前的问题时给了你这个错误,抱歉。)

需要更改authenticate_user_async中调用f的行。改变这个:

f(self, *args, **kwargs)

对此:

yield f(self, *args, **kwargs)

现在交换on_message的装饰顺序:

@authenticate_user_async
@gen.coroutine
def on_message(self, data):

authenticate_user_async中,“f”是您的on_message。这两个修复程序确保“f”是一个协程并且它可以运行完成。