Python 中的静态类方法属性

发布于 2025-01-19 08:21:57 字数 1426 浏览 4 评论 0原文

正如标题所说,我正在尝试为Python的静态课程提供设置/获得功能。基本上,对于具有静态属性的给定静态类_x,我想定义静态属性x,该 x 为_x 。

奇怪的是,似乎官方的Python文档说应该存在这种功能。 docs 说截至版本3.9,您可以使用<<<<<代码> @ClassMethod 装饰器以包装属性方法。但是,看来这仅适用于Getters,而不适合固定器。例如,当我尝试使用此方法定义静态属性时,我会收到以下错误:

class Foo:
  _x = 0

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

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

attributeError:'classMethod'对象没有属性'setter'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 返回属性对象,而不是调用属性的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,它不会调用属性设置器,而是完全覆盖x。

我看到的一种解决方案是使用Python元素来实现此功能。尽管可以解决这个问题,但这并不理想。

一段时间以来,我一直在寻找解决这个问题的解决方案,我不确定最好的“ Pythonic”修复程序是什么。如果元类是“最清洁”的解决方案,我该如何以不必编写很多冗余代码的方式来实现它们?也许我可以编写一个自定义功能装饰器,以启用类属性属性功能?任何帮助将不胜感激。

As the title says, I'm trying to give set/get functionality to my static classes in python. Basically, for a given static class with static attribute _x, I want to define a static property x that gives custom get and set function wrappers for _x.

Strangely it seems like the official Python docs say this functionality should exist. The docs say that as of version 3.9, you can use the @classmethod decorator to wrap property methods. However, it seems that this only works for getters, and not setters. For example, when I try to define a static property using this method, I get the following error:

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'

If I flip the order, like:

class Foo:
  _x = 0

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

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

Then Foo.x returns a property object instead of calling the property's fget function.

So it seems this approach is not going to work. I then tried to exploit the way that function decorators work, by redefining 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))

But no luck. Whenever I try to set Foo.x, i.e. with Foo.x = 2, it does not call the property setter but instead directly overwrites x entirely.

One solution I've seen bounced around is using python metaclasses to implement this functionality. While that could fix the issue, it isn't ideal because A. I have many different static classes in my project and B. I use Sphinx to generate documentation for my code and it doesn't always play nice with metaclasses.

I've been looking for a solution to this issue for a while and I'm not sure what the best "pythonic" fix for it is. If metaclasses are the "cleanest" solution, how can I implement them in such a way that I don't have to write a lot of redundant code? Maybe I could write a custom function decorator that enables class property-esque functionality? Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暮光沉寂 2025-01-26 08:21:57

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

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

尽管使用元类有缺点,但这就是有效的方法。

An instance's properties must be defined on its class. To define properties on a class, the rule still holds: when considering the class as an instance, its properties must be defined on the class's class (its metaclass).

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

Despite the drawbacks of using metaclasses, this is the way that works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文