【问题标题】:How to apply properties on classmethod?如何在类方法上应用属性?
【发布时间】:2015-01-13 03:29:21
【问题描述】:

我的问题很简单:如何向 classmethod 添加属性和设置器?

这是我的代码:

class Ingredient():
     __max_stock = 100
     __stock = 0
     __prix = 0

     def __init__(self):
         pass

     @classmethod
     @property
     def prix(cls):
         return cls.__prix
     @classmethod
     @prix.setter
     def prix(cls, value):
         assert isinstance(value, int) and int(abs(value)) == value
         cls.__prix = value


Ingredient.prix = 10        #should be OK
Ingredient.prix = 'text'    #should raise an error
Ingredient.prix = 10.5      #should raise an error too

问题是当 var 是类变量时,setter 不起作用。 这是我得到的错误:

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

我使用 Python 3.x

【问题讨论】:

  • 必须是classmethod吗?为什么不直接将默认值传递给构造函数,以便在需要时更改?
  • 我不确定propertyclassmethod 是否打算一起工作
  • 首先,感谢您美化了我的代码。其次,我要保留classmethod的原因是价格对所有成分都是通用的。因此,当我想更改价格时,所有实例都会有更新的价格(以 stock 和 max_stock 依此类推)
  • @EliasRhouzlane,我认为我的回答可以做到这一点。你能测试一下吗?
  • 我只想记录 Ingredient.prix 必须是一个非负整数。如果用户将其设置为其他内容,那么,caveat programmator。无论如何,您无法阻止他们直接将 Ingredient._Ingredient__prix 设置为某个值。

标签: python oop python-3.x properties setter


【解决方案1】:

这在 python 中是可能的 >= 3.9 per https://docs.python.org/3/howto/descriptor.html#id27For example, a classmethod and property could be chained together

您可能有一个用例,您只想计算一次类方法属性,然后继续使用该值。如果是这种情况并且需要对子类进行此计算,则可以在 python >= 3.6 中使用init_subclass 来执行此操作

class A:
    @classmethod
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.prix = cls._prix

class B(A):
    _prix = 0

【讨论】:

    【解决方案2】:

    不要以这种方式直接使用classmethod。如果您需要一个类似于实例属性装饰器的类属性装饰器,包括设置器的可能性,请查看other questions 以获得一些好的模式。 (您也可以使用元类来实现,但可能没有理由这样做。)

    【讨论】:

      猜你喜欢
      • 2016-07-18
      • 1970-01-01
      • 1970-01-01
      • 2015-02-02
      • 1970-01-01
      • 2015-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多