Reputation: 119
My question is simple: How can I add properties and setter to classmethod ?
Here is my code:
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
Problem is that the setter doesn't work when the var is a class variable. Here is the error I get :
AttributeError: 'classmethod' object has no attribute 'setter'
I use Python 3.x
Upvotes: 0
Views: 5223
Reputation: 2699
This is possible in python >= 3.9 per https://docs.python.org/3/howto/descriptor.html#id27
See For example, a classmethod and property could be chained together
You may have a use case where you only want to calculate a classmethod property one time then keep using that value. If that is the case and this calculation needs to be done on subclasses, one could use init_subclass in python >= 3.6 to do this
class A:
@classmethod
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.prix = cls._prix
class B(A):
_prix = 0
Upvotes: 2
Reputation: 611
Don't use classmethod directly in this way. If you need a classproperty decorator that is analogous to the instance property decorator including the possibility of setters, check out other questions for some good patterns. (You could also do it with a metaclass, but there's probably no reason to get into that.)
Upvotes: 1