Paul Prescod wrote: > Gordon McMillan wrote: > > > > What happens here (and when): > > class A: > > y = None > > class B(A): > > def __XXX_y__(self): > > ... > > I would say that the latter would just take precedence over the > former as if you had typed: > > class B(A): > __XXX_y__=ComputedAttribute( foo, bar, baz ) OK. I gather that the ComputedAttribute is actually named after the attribute. So in this situation, "y" is found in B.__dict__, and is a ComputedAttribute which hides A's (normal) attribute. Then: class A: def __init__(self): self.y = <something> class B(A): def __set_y__(self, value): ... def __init__(self): A.__init__(self) means that the hook in B will be invoked when A.__init__ runs. I wonder what "gotchas" lie in wait ;-). > > Hmmm. Current Python: search for y fails, try __getattr__. > > Proposed: search for y fails, try the __get_y__, then > > __getattr__. We've still done the same work before trying the > > hook, so how is performance affected? I hadn't realized when I wrote that that the ComputedAttribute would have the attribute's name. That does make getattr faster. But: > Actually, I was justifying Python's current behavior as much as I > was the current behavior. A truly general __getattr__ would > access all attribute tests, not just non-existent attributes and > thus be symmetric with setattr. But that would also be slow as > hell. I use __getattr__ most often to do lazy evaluation. So: def __getattr__(self, nm): if nm == 'doohickies': rslt = self.doohickies = <long calc> return rslt Yes, you can do this either way, but I rather like the fact that it's a last resort hook. > > class A: > > def __get_y__(self): > > ... > > class B(A): > > def __set_y__(self, value): > > .... > > My first instinct is just to disallow this and figure it out > after we have some more usage information/implementation > resources. We could just say that all methods must be defined in > the same class and if not. In other words, the methods "shadow > each other" as a group. > > This is no more messy than inherited __getattr__ s. Not at all. The complexity of doing __getattr__ and __setattr__ hooks is all in the class you implement them in. There's no *new* complexity in going to base class implementations - you just chain as usual. The only surprise might be that if the hapless subclasser doesn't realize that some base class has a __setattr__ hook set. I'm not against this proposal. But I think there are *no* "safe" ways of doing attr hacks; and simply getting to "safer" may be a whole lot of work. [I also note that there are quite a few Python developers who want their users to say "x = obj.getx()", but want Python to create the accessor method "getx(self)" (if they haven't written one) and outlaw "x = obj.x". I have no sympathy for them, but they exist.] - Gordon
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4