There are several ways to fix it. The simplest would be to create a
new property object in CC's definition:
class CC(C):
def set_value(self, val):
if val < 0:
self.__val = 1
else:
self.__val = val
value = property(C.get_ value, set_value)
It won't fix because __val is defined as a class variable in C, but as
an instance variable in CC. The set_value method creates a new __val. A
typical Python pitfall. C.get_value would still return _C__val.
But an easier, more flexible method would be to use a metaclass which
automatically adds properties for specially-named methods. One
example of such a metaclass is autoprop from Guido van Rossum's descrintro
essay; see <URL:http://www.python.org/2.2.3/descrintro.html >.
Yes, but i dislike it either. This powerfull metaclass approach
obscures the property creation right in the place. And it supports the
tendency to create fat frameworks. A few weeks ago i talked to someone
who avoided propertys completely because they seemed to Javaesque to
him. I first agreed and understood his ranting about this awkward
get_bla, set_blubb stuff. Then I rembebered that the property()
function is just a descriptor-creator and one can easily wrap around it
for simplification.
So i defined defprop()
def defprop(name, default = None, modify=None, check=None, types=[]):
name = "__"+name
def get(obj):
if not hasattr(obj,nam e):
setattr(obj,nam e, default)
return getattr(obj,nam e)
def set(obj,value):
if types:
if not True in [isinstance(valu e,t) for t in types]:
raise TypeError, "Can't assign %s to property
%s."%(value,nam e[2:])
if check:
if not check(value):
raise TypeError, "Can't assign %s to property
%s."%(value,nam e[2:])
if modify:
setattr(obj,nam e,modify(value) )
else:
setattr(obj,nam e,value)
return property(get,se t,None)
I left out to define delete. It was for demonstration purposes only.
Now define Your own classes:
class X(object):
a = defprop("a")
b = defprop("b",typ es=(tuple,list) )
c = defprop("c",che ck = lambda x:hasattr(x,"__ len__"))
d = defprop("d",def ault=0)
class XX(X):
def set_d(val):
if val<0:
return 1
return val
d = defprop("d",def ault=0,modify=s et_d) # overwrite d
It would be nice also to refuse the redundant naming a = defprop("a")
and write
a = defprop() instead. But it's actually not possible at the moment (
or only with deep introspection ).
Session on:
x = X()
x.d
0 xx = XX()
xx.d
0 xx.d = -1
xx.d
1
Ciao
Kay