我的装饰函数的参数正在交换。
在authorized(self, resp)
中,resp
正在成为ClientView
个对象,而self
正在成为resp
变量。
我如何装饰这个函数,以便它可以用作方法?
它使用烧瓶类视图和flask_oauthlib。
功能代码:
class ClientView(UserView):
@bp.route('/vklogin/authorized')
@vk.authorized_handler
def authorized(self, resp):
if resp is None:
return 'Access denied: reason=%s error=%s' % (
request.args['error_reason'],
request.args['error_description']
)
session['oauth_token'] = (resp['access_token'], '')
me = self.vk.get('method/users.get?uids={}'.format(resp['user_id']))
return '{}'.format(me.data)
装饰功能代码:
class OAuthRemoteApp(object):
def authorized_handler(self, f):
@wraps(f)
def decorated(*args, **kwargs):
if 'oauth_verifier' in request.args:
try:
data = self.handle_oauth1_response()
except OAuthException as e:
data = e
elif 'code' in request.args:
try:
data = self.handle_oauth2_response()
except OAuthException as e:
data = e
else:
data = self.handle_unknown_response()
# free request token
session.pop('%s_oauthtok' % self.name, None)
session.pop('%s_oauthredir' % self.name, None)
return f(*((data,) + args), **kwargs)
return decorated
答案 0 :(得分:0)
考虑代码的简化(和可运行)版本代码:
class OAuthRemoteApp(object):
def authorized_handler(self, f):
def decorated(*args, **kwargs):
print(self, f, args, kwargs) #1
# (<__main__.OAuthRemoteApp object at 0xb74d324c>, <function authorized at 0xb774ba04>, (<__main__.ClientView object at 0xb74d32cc>,), {})
data = 'resp'
print((data,) + args) #2
# ('resp', <__main__.ClientView object at 0xb74d32cc>)
return f(*((data,) + args), **kwargs)
return decorated
vk = OAuthRemoteApp()
class ClientView(object):
@vk.authorized_handler
def authorized(self, resp):
print(self, resp) #3
# ('resp', <__main__.ClientView object at 0xb7452eec>)
cv = ClientView()
cv.authorized()
请注意args
中的第一项是ClientView
个实例:
args = (<__main__.ClientView object at 0xb74d32cc>,)
(data,) + args
位于'resp'
之前
ClientView
个实例。这是问题的根源。self
为resp
,resp
为ClientView
实例。这些参数的输入顺序错误。解决问题的一种方法是在第一项后插入data
在args
:
class OAuthRemoteApp(object):
def authorized_handler(self, f):
def decorated(*args, **kwargs):
data = 'resp'
args = args[:1] + (data,) + args[1:]
return f(*args, **kwargs)
return decorated
vk = OAuthRemoteApp()
class ClientView(object):
@vk.authorized_handler
def authorized(self, resp):
print(self, resp)
cv = ClientView()
cv.authorized()
产量
(<__main__.ClientView object at 0xb7434f0c>, 'resp')
显示以正确顺序提供的ClientView
和resp
参数。