On Thu, 31 Dec 2015 12:12:43 +0000, Oscar Benjamin wrote:
> When you write x.attr the name 'attr' is looked up on the object x. This > calls x.__getattribute__('attr'). In turn this checks the dict > associated with the object x i.e. x.__dict__['attr']. This in turn calls > x.__dict__.__getitem__('attr'). The lookup of x.__dict__ is special and > doesn't use the normal __getattribute__ mechanism (otherwise this would > be an infinite recursion). Generally special attributes (with double > underscores) are looked up in a different way. If x.__dict__ does not > have the attribute then the dict associated with the class/type of x is > checked i.e. x.__class__.__dict__['attr']. The lookup of x.__class__ is > also special. Failing this the other classes in x.__class__.__mro__ are > checked i.e. x.__class__.__mro__[1].__dict__['attr']. Once these are > exhausted x.__getattribute__('attr') falls back on calling > x.__getattr__('attr'). Very good overview of the steps, thank you. ...> > The problem with this as with any dict subclass approach is that a dict > has a load of methods (.items() .keys() .pop() ...) that will now become > conflated with your dict keys when you use the attribute access: > >>>> d.items > <built-in method items of attrdict object at 0x7f2025eab868> Yeah, this makes it confusing, too. :) -- https://mail.python.org/mailman/listinfo/python-list