首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在python3装饰器中的方法调用中没有参数'self‘的值

在python3装饰器中的方法调用中没有参数'self‘的值
EN

Stack Overflow用户
提问于 2020-08-27 15:01:28
回答 1查看 377关注 0票数 0

我正在尝试在类中使用修饰器,并在pylint中得到一个在线错误

@start_test_min_pg(min_version_pg="9.5")

方法调用中的参数'self‘没有价值

代码语言:javascript
复制
class TestsUnloggedTabled(BaseTester):
   some code

   def get_pg_version(self):
       pg_temp = Postgres(self.host, self.port, self.username, self.password, "postgres")
       current_pg_version = pg_temp.query("show server_version")[0][0].split(" ")[0]
       print('PG version is: ' + current_pg_version)
       return current_pg_version

   def start_test_min_pg(self, min_version_pg):
       def decorator_repeat(func):
           @functools.wraps(func)
           def wrapper_repeat(*args, **kwargs):
               if LooseVersion(self.get_pg_version()) > LooseVersion(min_version_pg):
                   value = func(*args, **kwargs)
                   return value
               return wrapper_repeat
           return decorator_repeat

   @start_test_min_pg(min_version_pg="9.5")
   def test_schema_hashing(self):
       do something
EN

回答 1

Stack Overflow用户

发布于 2020-08-28 06:50:00

按照编写装饰器的方式,需要在类的实例上调用它才能正常工作。也就是说,您需要将其应用于:

代码语言:javascript
复制
obj = TestsUnloggedTabled(...)

@obj.start_test_min_pg(min_version_pg="9.5")
def foo():
    pass

当您将它应用到同一个类中的另一个方法时,这显然无法工作,因为在类定义结束之前,您无法创建一个实例。因此,您显然不希望将装饰器作为方法调用,这意味着您不应该将self作为其参数之一。

但是在以后的代码实现中确实需要self。你从哪弄到的?好的,一旦定义了类,wrapper_repeat函数就是在实际实例上调用的函数。因此,它的第一个参数将是该实例,您可以将它命名为self,而不是让它与args中的其他位置参数一起收集。在调用原始函数时,您确实需要记住传递它。

代码语言:javascript
复制
def start_test_min_pg(min_version_pg):                            # no self here
   def decorator_repeat(func):
       @functools.wraps(func)
       def wrapper_repeat(self, *args, **kwargs):                 # put it here instead
           if LooseVersion(self.get_pg_version()) > LooseVersion(min_version_pg):
               value = func(self, *args, **kwargs)                # and pass it along
               return value
       return wrapper_repeat
   return decorator_repeat

注意,我修正了这段代码最后两行的缩进级别,您问题中的版本将不能正常工作(因为装饰工厂将返回None)。我猜这可能是将代码复制到堆栈溢出中的一个工件,而不是实际代码中的错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63618839

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档