我编写了一个装饰器来验证调用。仅使用一个参数时它可以正常工作,但使用更多参数时就不行了,触发 inner() 恰好需要 1 个参数(给定 2 个)
。由于我使用 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)
编辑:
将代码更新为工作版本。
谢谢!
最佳答案
我一开始以为问题很简单,但后来你发布了一个与原始错误消息相矛盾的回溯。然而,我认为问题仍然非常简单,假设回溯错误是正确的。回想一下:
@decorator
def foo(x):
return x + 1
只是语法糖:
def foo(x):
return x + 1
foo = oauth_machine.auth(foo)
因此,当您在 get
上使用 @oauth_machine.auth
时,它会通过闭包作为 fn
传递到 inner
中>.
def auth(fn):
def inner(self):
res = get_user_by_credentials(self, fn, callback=done_auth)
return inner
然后它再次作为 fn
传递到 get_user_by_credentials
,这又产生另一个闭包,该闭包将 fn
传递给 callback
。
def get_user_by_credentials(self, fn, callback):
def onFetchUserCredentials(result, error):
self.user = result
callback(self, fn)
callback
被定义为 inner
中的 done_auth
,因此意味着 fn
(即原来的 get
) 被传递到那里,然后调用 result
:
def done_auth(result, fn):
return fn(result)
但是fn
(即get
)需要两个参数。您只传递一个,导致错误。
关于具有多个参数的 python 装饰函数(Tornado),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13426793/