Python 中的静态 class 方法属性

Static class method properties in Python

正如标题所说,我正在尝试为 python 中的静态 classes 提供 set/get 功能。基本上,对于具有静态属性 _x 的给定静态 class,我想定义一个静态 属性 x_x 提供自定义获取和设置函数包装器.

奇怪的是,官方 Python 文档似乎说这个功能应该存在。 The docs 表示从 3.9 版开始,您可以使用 @classmethod 装饰器来包装 属性 方法。但是,这似乎只适用于吸气剂,而不适用于 setters。例如,当我尝试使用此方法定义静态 属性 时,出现以下错误:

class Foo:
  _x = 0

  @classmethod
  @property
  def x(self):
    return self._x

  @classmethod
  @x.setter
  def x(self, n):
    self._x = n

AttributeError: 'classmethod' object has no attribute 'setter'

如果我翻转顺序,例如:

class Foo:
  _x = 0

  @property
  @classmethod
  def x(self):
    return self._x

  @x.setter
  @classmethod
  def x(self, n):
    self._x = n

然后 Foo.x returns 一个 属性 object 而不是调用 属性 的 fget 函数。

看来这种方法行不通。然后我尝试通过重新定义 Foo:

来利用函数装饰器的工作方式
class Foo:
  _x = 0

  def __get_x(self):
    return self._x

  def __set_x(self, n):
    self._x = n

  x = classmethod(property(fget=__get_x, fset=__set_x))

但运气不好。每当我尝试设置 Foo.x,即使用 Foo.x = 2 时,它不会调用 属性 setter 而是直接完全覆盖 x。

我见过的一种解决方案是使用 python metaclasses 来实现此功能。虽然这可以解决问题,但它并不理想,因为 A. 我的项目中有许多不同的静态 classes 和 B. 我使用 Sphinx 为我的代码生成文档,但它并不总是与元classes.

我一直在寻找这个问题的解决方案,但我不确定最好的“pythonic”修复是什么。如果 metaclasses 是“最干净”的解决方案,我怎样才能以不必编写大量冗余代码的方式实现它们?也许我可以编写一个启用 class property-esque 功能的自定义函数装饰器?任何帮助将不胜感激。

实例的属性必须在其 class 上定义。要在 class 上定义属性,规则仍然成立:当将 class 视为实例时,其属性必须在 class 的 [=16] 上定义=] class(它的元class)。

class Meta(type):

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, n):
        self._x = n

class Foo(metaclass=Meta):
    _x = 0

尽管使用 metaclasses 有缺点,但这是可行的方法。