【问题标题】:python using self in decorators in class with kwargpython在带有kwarg的类中使用self在装饰器中
【发布时间】:2016-09-05 01:36:58
【问题描述】:

所以我有这组代码,测试装饰器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 进去

【问题讨论】:

  • 第一个参数是selfkwargs 是第二个。
  • 但经过身份验证接受 self 和 **kwargs,怎么了?
  • 您可能正在寻找argument unpacking
  • 还是同样的错误
  • 请将错误的完整回溯添加到您的问题中,这样我们就不必一直猜测这里到底抱怨了什么。

标签: python class decorator python-decorators


【解决方案1】:

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

return func(self, **kwargs)

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

if not self.authenticated(**kwargs):

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

【讨论】:

  • 那么请提供您问题中错误的完整追溯。你的问题不仅仅是我在那个案例中指出的问题。
  • 刚刚意识到我需要重新启动服务器才能看到更改受到影响。这就是为什么它一直提示旧错误的原因。
  • 我们可以在实例中制作装饰器吗?使用自我的意思
  • @LeDuyKhanh:装饰器应用于函数,一旦类体完成,结果就会添加到类对象中。然后函数对象充当descriptors,这意味着当在实例上查找时,它们会生成一个绑定到实例的方法。所以你的wrap函数被绑定为一个方法并传入了self,但原来的func函数没有,所以你必须显式传入self
猜你喜欢
  • 1970-01-01
  • 2012-04-21
  • 2016-04-23
  • 2018-12-02
  • 2020-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多