Peter said:
Laszlo Zsolt Nagy wrote:
You could define a "normal" property in the metaclass:
The only way I could do this is:
class MyXMetaClass(type):
_x = 0
def get_x(cls):
print "Getting x"
return cls._x
def set_x(cls,value):
cls._x = value
print "Set %s.x to %s" % (cls.__name__,value)
x = property(get_x,set_x)
class A(object):
__metaclass__ = MyXMetaClass
print A.x
A.x = 8
Results in:
Getting x
0
Set A.x to 8
But of course this is bad because the class attribute is not stored in
the class. I feel it should be.
Suppose we want to create a class property, and a class attribute; and
we would like the property get/set methods to use the values of the
class attributes.
A real example would be a class that keeps track of its direct and
subclassed instances:
class A(object):
cnt = 0
a_cnt = 0
def __init__(self):
A.cnt += 1
if self.__class__ is A:
A.a_cnt += 1
class B(A):
pass
print A.cnt,A.a_cnt # 0,0
b = B()
print A.cnt,A.a_cnt # 1,0
a = A()
print A.cnt,A.a_cnt # 2,1
But then, I may want to create read-only class property that returns the
cnt/a_cnt ratio.
This now cannot be implemented with a metaclass, because the metaclass
cannot operate on the class attributes:
class A(object):
cnt = 0
a_cnt = 0
ratio = a_class_property_that_returns_the_cnt_per_a_cnt_ratio() # ????
def __init__(self):
A.cnt += 1
if self.__class__ is A:
A.a_cnt += 1
Any ideas?
Les