Michael Foord a écrit : > On 20/03/2010 12:00, Pascal Chambon wrote: >> >> >> But the point which for me is still unclear, is : does the default >> implementation of __getattribute__ (the one of "object") call >> __getattr__ by himself, or does it rely on its caller for that, by >> raising an AttributeError ? For Python2, it's blatantly the latter >> case which is favoured, but since it looks like an implementation >> detail at the moment, I propose we settle it (and document it) once >> for all. > > Ah right, my apologies. So it is still documented behaviour - > __getattr__ is obviously called by the Python runtime and not by > __getattribute__. (It isn't just by getattr as the same behaviour is > shown when doing a normal attribute lookup and not via the getattr > function.) > I really don't see the docs you're referring to ; until I tested myself, I think I had no obvious reasons to guess that __getattribute__ relied on the upper level caller instead of finishing the hard job himself. Nick Coghlan a écrit : > Michael Foord wrote: > >> Well, the documentation you pointed to specifies that __getattr__ will >> be called if __getattribute__ raises an AttributeError, it just doesn't >> specify that it is done by object.__getattribute__ (which it isn't). >> > > And as for why not: because __getattribute__ implementations need to be > able to call object.__getattribute__ without triggering the fallback > behaviour. > > Cheers, > Nick. > > I guess there are cases in which it is beneficial indeed. > > Michael Foord wrote: > >> Well, the documentation you pointed to specifies that __getattr__ >> will be called if __getattribute__ raises an AttributeError, it just >> doesn't specify that it is done by object.__getattribute__ (which it >> isn't). > > If __getattribute__ raises an exception, it won't get a chance to > do anything else, so something outside of __getattribute__ must > catch the AttributeError and calling __getattr__. So I think the > docs *are* specifying the behaviour here, if only by implication. > I don't follow you there - in my mind, the default __getattribute__ could simply have wrapped all its operations inside soem kind of "try..catch AttributeError:" mechanism, and thus been able to fallback to __getattr__ in any way. If I sum it up properly the semantic is : -A.obj and getattr(A, "obj") are exactly the same -They trigger the calling of __getattribute__ on the object (or it's python core equivalent) -By default, this __getattribute__ browse the whole object hierarchy according to well known rules (__dict__, type, type's ancestors..), handling descriptor protocols and the like. But it doesn't fallback to __getattr__ - it raises an AttributeError instead. -getattr() falls back to __getattr__ if __getattribute__ fails -customized __getattribute__ methods have the choice between calling __getattr__ by themselves, or delegating it to getattr() by raising an exception. Wouldn't it be worth completing the doc with these point ? They really didn't seem obvious to me basically (even though, after analysis, some behaviours make more sense than others). I might submit a patch. regards, Pascal > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20100322/c908270b/attachment-0001.html>
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