Bruno Desthuilliers wrote: > Rich Harkins a écrit : >> [EMAIL PROTECTED] wrote: >>> Hello everyone, >>> >>> I'm trying to do seemingly trivial thing with descriptors: have >>> another attribute updated on dot access in object defined using >>> descriptors. >> [snip] >> >>> A setter function should have updated self.l just like it updated >>> self.s: >>> >>> def __set__(self, obj, val): >>> self.s=val >>> self.l=len(val) >>> print "setting value:", self.s, "length:", self.l >>> >>> Yet it didn't happen. >>> >> [snip] >> >> I noticed that Python will block all attribute overrides (either via >> __dict__ through setattr) if the property has a __set__ method. > > It doesn't "block", it controls access to... Of course, if the __set__ > method is a no-op, then nothing will happen. > >> The >> standard property has this method and there is no way that I can find to >> defeat it. > > "defeat" ? Why don't you just pass the appropriate fset function to > property ? > >> So, here is what I use: >> >> class ConstProperty(object): >> """ >> Provides a property that keeps its return value. The function will >> only be called on the first access. After that the same value can >> be used over and over again with no function call penalty. If the >> cached value needs to be cleared, simply del the attribute. >> >> >>> class MyClass(object): >> ... def __init__(self, x): >> ... self.x = x >> ... @ConstProperty >> ... def y(self): >> ... print "HERE" >> ... return self.x ** 2 >> ... >> >>> obj = MyClass(5) >> >>> obj.y >> HERE >> 25 >> >>> obj.y >> 25 >> """ >> >> def __init__(self, fn): >> self.fn = fn >> >> def __get__(self, target, cls=None): >> if target is None: >> return self.fn # Helps pydoc >> else: >> obj = self.fn(target) >> setattr(target, self.fn.__name__, obj) >> return obj > > > > >>> m = MyClass(5) > >>> m.__dict__ > {'x': 5} > >>> m.y > HERE > 25 > >>> m.__dict__ > {'y': 25, 'x': 5} > >>> m.x = 42 > >>> m.y > 25 > >>> m.__dict__ > {'y': 25, 'x': 42} > >>> > > > I'm sorry, but this looks like a very complicated way to do a simple thing: > > class MySimpleClass(object): > def __init__(self, x): > self.x = x > self.y = x ** 2 > >
-- http://mail.python.org/mailman/listinfo/python-list