[EMAIL PROTECTED] a écrit : > On Feb 6, 11:09 pm, "[EMAIL PROTECTED]" > <[EMAIL PROTECTED]> wrote: >> While this is technically possible (I tried a couple years ago), it >> requires hacking the __getattribute__ method, which is something I >> would not recommand, not only because it can be tricky, but mostly >> because this is a very critical path wrt/ perfs. (IIRC it also >> required using custom descriptors, but I'm not really sure about this >> last point). > > Performance is pretty important for the class I'm designing so I think > __getattribute__ is probably out. The computed properties are only > infrequently accessed, but using __getattribute__ slows everything > down, right?
Indeed - it *is* the attribute lookup mechanism. Better to leave it alone. >> Before new-style classes, we used the __getattr__/__setattr__ hooks >> for computed attributes. While this approach is now a bit abandonned >> in favor of descriptors (properties or custom ones), it still works >> fine, and is probably the best solution to your problem. > > Ah, I didn't know about these - it looks as though they might be just > the thing since it seems they're only called after all the other > methods fail. Right. > That looks like there would be no performance hit, I > wouldn't need to mess around with dynamically changing the class, and > it would automatically deal with the (irritating) feature of having to > check if there is already something in the object's dir() with that > name. I'll look into this tomorrow - I hope this feature isn't going > to be removed in future versions of Python? I really don't think so. It's still has it's use for automatic delegation. And, as is the case here, for per-instance computed attributes. As a side note: the naming symetry between __getattr__ and __setattr__ is a gotcha, since __setattr__ is mostly symetric to __getattribute__ - IOW, customizing __setattr__ is a bit tricky. The naive approach, ie: class Parrot(object): def __setattr__(self, name, val): self.name = val will indeed go into infinite recursion (or would, if the interpreter didn't stop it after a while) The solution is of course to call on the parent class's __setattr__: class Ni(object): def __setattr__(self, name, val): object.__setattr__(self, name, value) HTH -- http://mail.python.org/mailman/listinfo/python-list