2014-11-15 31 views
0

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

问题是,当该变种是一个类变量的setter不起作用。 这里是我的错误:

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

我使用Python 3.x的

+0

它是否必须是'classmethod'?为什么不只有一个默认值传递给构造函数,您可以在需要时进行更改? –

+1

我不确定'财产'和'classmethod'是否打算*一起工作 – chepner

+0

首先,最重要的是,感谢您对我的代码进行了美化。 其次,我想保持classmethod的原因是价格是所有成分通用的。所以当我想改变价格时,所有的实例都会有一个更新的价格(以及stock和max_stock等) –

回答

1

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

-1

免责声明:OP和我曾指出,这不工作(见注释)。这是一个善意的尝试来解决这个问题。我们只是在这里留下后代。

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

    def __init__(self): 
     pass 

    @property 
    def prix(cls): 
     return cls.__prix 
    @prix.setter 
    def prix(cls, value): 
     if isinstance(value, int) and value >= 0: 
      cls.__prix = value 
     else: 
      # il faut que value soit...? 
      raise ValueError('`value` must be a positive integer') 


Ingredient.prix = 100 

i_1 = Ingredient() 
print(i_1.prix) 

Ingredient.prix = 40 
i_2 = Ingredient() 

print(i_1.prix, i_2.prix) 

它打印:

100 
40, 40 

所以它似乎工作,对不对?

+0

它不起作用。如果我做Ingredient.prix ='文本',它不会像我在setter –

+0

@EliasRhouzlane中定义的那样引发错误,你是对的。不知道这里还有什么要做。 –

+0

无论如何感谢您的帮助,非常酷! –

相关问题