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