python装饰功能与多个args(龙卷风)

时间:2012-11-17 01:36:49

标签: python arguments decorator tornado

我写了一个装饰器来验证通话。只使用一个参数,它可以正常工作,但如果没有,则触发inner() takes exactly 1 argument (2 given)。我有一个回调意大利面,因为我正在使用龙卷风,但我不确定这是最好的方法。

#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)

编辑:

将代码更新为工作版本。

谢谢!

1 个答案:

答案 0 :(得分:1)

我一开始以为这个问题很简单,但是你发布了一条与原始错误信息相矛盾的追溯。但是,我认为问题仍然非常简单,假设 traceback 错误是正确的错误。回想一下:

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

这只是语法糖:

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

因此,当您在@oauth_machine.auth上使用get时,它会通过闭包传递到inner fn

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

然后将其作为get_user_by_credentials传递给fn,然后又生成另一个闭包,将fn传递给callback

def get_user_by_credentials(self, fn, callback):

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

callbackdone_auth中被定义为inner,因此fn(即原始get)的menas会在那里传递,然后被调用在result

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

但是fn(即get)有两个参数。您只传递一个,导致错误。