using __getitem()__ correctly

Charles T. Smith cts.private.yahoo at gmail.com
Thu Dec 31 08:39:30 EST 2015


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.  :)



More information about the Python-list mailing list