python 在 class 的装饰器中使用 self with kwarg

python using self in decorators in class with kwarg

于是就有了这组代码,测试装饰器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。我真的不知道怎么了?而我只传递了一个 kwarg

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

return func(self, **kwargs)

您的 authenticated 方法实际上并未 使用 您传入的 kwargs 字典,因此您可以调用 self.authenticated(),但如果您需要访问这些关键字参数,您可能也想在那里使用 **kwargs 调用语法:

if not self.authenticated(**kwargs):

由于您在 调用 修饰函数时看到错误,您可能传入了 positional 参数,但您的包装器仅接受 关键字参数 (超出 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):
    # ...