python在类中的装饰器中使用self与kwarg

时间:2016-05-10 07:51:56

标签: python class decorator python-decorators

所以我有这组代码,测试装饰器base_permissions_check

def authenticated(self,*arg,**kwargs):
    function_call = inspect.stack()[1][4][0].strip()
    matched = re.match('^self\.', function_call)
    if not matched:
        raise Exception("function is private")

    return self.user.is_authenticated()

def base_permissions_check(func):
    def wrap(self,**kwargs):

        if not self.authenticated(kwargs):
            return self.permissions
            # func(kwargs)
        return func(kwargs)
    return wrap

#public
@base_permissions_check
def has_video_permission(self,**kwargs):

当我调用has_video_permission时,错误显示authenticated() takes 1 positional argument but 2 were given。我真的不知道出了什么问题?虽然我只把一只小马扔进去了

1 个答案:

答案 0 :(得分:2)

包装的func()函数未作为方法绑定到实例,因此您需要显式传入self。您还需要使用kwargs调用语法将**kwargs字典应用为单独的关键字参数:

return func(self, **kwargs)

您的authenticated方法实际上使用您传入的kwargs词典,因此您只需拨打self.authenticated(),但如果您需要访问权限对于那些关键字参数,您可能也希望在那里使用**kwargs调用语法:

if not self.authenticated(**kwargs):

由于您在调用装饰函数时看到错误,您可能正在传递位置参数,但您的包装器只接受关键字参数(超出self)。也许您想添加*args来处理这些位置参数:

def base_permissions_check(func):
    def wrap(self, *args, **kwargs):

        if not self.authenticated(**kwargs):
            return self.permissions
            # func(kwargs)
        return func(self, *args, **kwargs)
    return wrap

#public
@base_permissions_check
def has_video_permission(self, *args, **kwargs):
    # ...