如何在classmethod上应用属性?

时间:2014-11-15 23:33:06

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

我的问题很简单:如何将属性和setter添加到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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

您可能有一个用例,您只想一次计算classmethod属性,然后继续使用该值。如果是这种情况,并且此计算需要在子类上完成,则可以在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