2014-06-15 37 views
-1

我的装饰函数的参数正在交换。 在authorized(self, resp),resp变成了ClientView对象并且self变成resp变量。 我如何装饰这个功能,以便它可以用作一种方法?Python - 使用类中的装饰函数

它使用烧瓶类视图和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

考虑你的代码的这一简单求(和可运行的)版本代码:

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() 
  1. 注意第一项在argsClientView实例:

    args = (<__main__.ClientView object at 0xb74d32cc>,) 
    
  2. 表达(data,) + args预规划'resp'ClientView实例的前面。这是问题的根源。
  3. 请注意,这里selfresprespClientView 实例。参数以错误的顺序提供。来解决这个问题

的一种方式是在args中的第一项 之后插入data

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

其示出了被提供的ClientViewresp参数按正确的顺序。