python - 通过装饰器注入(inject)类属性

标签 python django pycharm decorator testcase

我有一大堆 Django 测试用例,它们使用 setUp 方法来初始化在众多测试中使用的一些属性,它们的构造方式和相互依赖的方式是我想要从测试用例中移出的逻辑,重用

def setUp(self):
    self.property_1 = ##some logic
    ...

我想将它们重写为一些方便的包装器,可以通过简单的继承或装饰器注入(inject)到类中,例如

@with_property_1(x=1, y=2)
def setUp(self):
    ...


def with_property_1(**model_kwargs):
    def wrapper(f):
        def wrapped(*args, **kwargs):
            self = args[0]
            self.property_1 = ## logic
            f(*args, **kwargs)
        return wrapped
    return wrapper

但问题是 PyCharm 无法识别这些实例属性的存在,因为 TestCase 类内部没有任何内容设置它们。是否有另一种方法可以很好地实现这一目标,或者有一种方法可以诱使 PyCharm 认识到这些属性在装饰器存在的情况下是合法的?

最佳答案

免责声明:未经测试。

这里的问题是 Python 不能神奇地将 self 放入装饰器的上下文中(这在任何 IDE 中都不起作用)。您可能忘记的是,self 是调用每个类方法时传递给它的参数之一。因此,它存在于您的 *args 中,您可以对其进行操作。

这是我的试用代码:

def with_property_1(**model_kwargs):
  def wrapper(f):
    def wrapped(*args, **kwargs):
      for key, value in model_kwargs.items():
        setattr(args[0], key, value)
      f(*args, **kwargs)
    return wrapped
  return wrapper

说明:

  1. 迭代 **model_kwargs 中的每个键/值。

  2. 使用 setattr 使用提供的 kwargs 修改 args[0],它应该是 self 变量。

  3. 使用更新后的 self 变量正常调用该函数。

关于python - 通过装饰器注入(inject)类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55209924/

相关文章:

django - 生成视频缩略图的最佳方法是什么?

python - 如何使用 django 表单编辑模型数据

python - 在 JetBrains PyCharm 中禁用 SQL 检测

python - 基本触发 : math. atan() 问题

python - 为什么 python 引用中的绑定(bind)实例方法不相等?

python - 您正在使用不受支持的命令行标志 : --ignore-certificate-errors. 稳定性和安全性将受到影响

python - Django:pycharm:未版本化的文件

python - 为什么这个异常不打印 0?

python - AWS Elastic Beanstalk 无法使用requirements.txt 安装Python 包 - Firebase-Admin

python - 使用内省(introspection)绑定(bind)在 pycharm 中完成代码