Prev: Access class from staticmethod
Next: Danny L.
From: kj on 30 Apr 2010 16:42 I want to define a class attribute that is computed from other class attributes. Furthermore, this attribute should be inheritable, and its value in the subclasses should reflect the subclasses values of the attributes used to compute the computed attribute. I tried the following: class Spam(object): X = 3 @property @classmethod def Y(cls): return cls.X * 3 ....but Spam.Y returns <property object at 0x......>, rather than 9. How can I define a "class property"? Is it possible at all? Ultimately, I'd like to be able to define multiple subclasses of Spam, e.g. class Ham(Spam): X = 7 class Eggs(Spam): X = '.' and have Ham.Y and Eggs.Y evaluate to 21 and '...', respectively. Thanks! ~K
From: Lie Ryan on 30 Apr 2010 17:38 On 05/01/10 06:42, kj wrote: > I want to define a class attribute that is computed from other > class attributes. Furthermore, this attribute should be inheritable, > and its value in the subclasses should reflect the subclasses values > of the attributes used to compute the computed attribute. I tried > the following: I believe you will need to deal with metaclass and the descriptor protocol (__get__/__set__) to have a computed class attribute. If anyone knows of simpler ways, please shout out. Anyway, 'property' only works for instances. The "property decorator" returns the "property descriptor" object, which has a __get__ and __set__ methods which defines how the attribute gets accessed from its instances. Now, remember that just like "instance" is an instance of "class", a "class" is an instance of "metaclass". Therefore if we want to make "class property", we need to define the property at the metaclass. Don't worry about these details. There are several ways to achieve what you wanted, the easiest probably would be: class MetaSpam(type): @property def Y(cls): return cls.X * 3 class Spam(object): __metaclass__ = MetaSpam and there we go: >>> class Ham(Spam): .... X = 7 .... >>> class Eggs(Spam): .... X = '.' .... >>> Ham.Y; Eggs.Y 21 '...' > class Spam(object): > X = 3 > @property > @classmethod > def Y(cls): > return cls.X * 3 > > ....but Spam.Y returns <property object at 0x......>, rather than 9. > > How can I define a "class property"? Is it possible at all? > > Ultimately, I'd like to be able to define multiple subclasses of > Spam, e.g. > > class Ham(Spam): > X = 7 > class Eggs(Spam): > X = '.' > > and have Ham.Y and Eggs.Y evaluate to 21 and '...', respectively. > > Thanks! > > ~K
From: kj on 30 Apr 2010 18:34 In <4bdb4e4f$1(a)dnews.tpgi.com.au> Lie Ryan <lie.1296(a)gmail.com> writes: >class MetaSpam(type): > @property > def Y(cls): > return cls.X * 3 >class Spam(object): > __metaclass__ = MetaSpam >and there we go: >>>> class Ham(Spam): >... X = 7 >... >>>> class Eggs(Spam): >... X = '.' >... >>>> Ham.Y; Eggs.Y >21 >'...' !!!hmmm!!! That's very interesting! I did not know about metaclasses; I need to learn more about them. Thanks for the pointer! ~K
|
Pages: 1 Prev: Access class from staticmethod Next: Danny L. |