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 有缺点,但这是可行的方法。
正如标题所说,我正在尝试为 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 有缺点,但这是可行的方法。