python - python3装饰器中的方法调用中参数'self'没有值
问题描述
我正在尝试在课堂上使用装饰器并在线 pylint 中出现错误
@start_test_min_pg(min_version_pg="9.5")
方法调用中的参数“self”没有值
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
解决方案
您编写装饰器的方式需要在您的类的实例上调用才能正常工作。也就是说,您需要将其应用于:
obj = TestsUnloggedTabled(...)
@obj.start_test_min_pg(min_version_pg="9.5")
def foo():
pass
当您将其应用于同一类中的另一个方法时,这显然不起作用,因为在类定义结束之前您无法创建实例。因此,您显然不想将装饰器作为方法调用,这意味着您不应该将self
其作为参数之一。
但是您确实需要self
稍后执行您的代码。你从哪里得到它?好吧,wrapper_repeat
一旦定义了类,该函数将在实际实例上调用。所以它的第一个参数将是那个实例,你可以命名它self
而不是让它与其他位置参数一起收集在args
. 您确实需要记住在调用原始函数时传递它。
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
)。我猜这可能是将代码复制到 Stack Overflow 中的人工制品,而不是在您的真实代码中实际上有问题的东西。
推荐阅读
- azure - 将用户从本地 SQL Server 迁移到 Azure Active Directory B2C 时如何保持登录名相同
- kubernetes - HELM 脚本在 json 值上循环
- google-apps-script - Stackdriver 日志未显示在 Google Apps 脚本中
- typescript - 从数据库加载有区别的联合
- github - 如何从 Azure devops 管道代理获取安全签名的工件
- unity3d - 为什么我的 Unity 游戏在构建后处于 Free Aspect
- c++ - 为什么添加多个虚函数时类的大小保持不变?
- vb.net - 如何从 Mathnet、vb.net 中的矩阵或向量中找到实体索引?
- php - 将用户插入sql数据库的问题
- flutter - 类String在flutter中没有实例getter