1

我写了一个装饰器来验证调用。它只适用于一个参数,但如果有更多参数则不能,触发inner() takes exactly 1 argument (2 given). 自从我使用 Tornado 以来,我有一些回调意大利面,但我不确定最好的方法是什么。

#this works
class FirstHandler(BaseHandler):

    @asynchronous
    @oauth_machine.auth
    def post(self):
        print self.user
        self.finish()

#this now also does
class SecondHandler(BaseHandler):

    @asynchronous
    @oauth_machine.auth
    def get(self, args):
        self.write("ok")
        self.finish()

装饰器功能

def auth(fn):
    def inner(self, *args):
        res = get_user_by_credentials(self, fn, args, callback=done_auth)
    return inner

def get_user_by_credentials(self, fn, callback):

    def onFetchUserCredentials(result, error):
        self.user = result
        callback(self, fn, args)

    email = self.get_argument("email")
    password = self.get_argument("password")
    settings.DB.users.find_one({'email': email, 'password': password }, callback=onFetchUserCredentials)

def done_auth(result, fn, args):
    return fn(result, args)

编辑 :

将代码更新为工作版本。

谢谢!

4

1 回答 1

2

起初我以为问题很简单,但后来您发布了与原始错误消息相矛盾的回溯。但是,我认为问题仍然很简单,假设回溯错误是正确的。回想一下:

@decorator
def foo(x):
    return x + 1

只是语法糖:

def foo(x):
    return x + 1
foo = oauth_machine.auth(foo)

因此,当您使用@oauth_machine.authon时get,它会通过闭包传递给inneras fn

def auth(fn):
    def inner(self):
        res = get_user_by_credentials(self, fn, callback=done_auth)
    return inner

然后它被传递到get_user_by_credentials,再次作为fn,这反过来又产生另一个闭包,它传递fncallback

def get_user_by_credentials(self, fn, callback):

    def onFetchUserCredentials(result, error):
        self.user = result
        callback(self, fn)

callback被定义为done_authback in inner,因此fn(即原始get)的menas 被传递到那里,然后被调用result

def done_auth(result, fn):
    return fn(result)

但是fn(ie get) 需要两个参数。你只传递一个,导致错误。

于 2012-11-17T02:18:06.017 回答