What is the difference between the .__ getattribute__ type and the .__ getattribute__ object?

Given:

In [37]: class A:
   ....:     f = 1
   ....:

In [38]: class B(A):
   ....:     pass
   ....:

In [39]: getattr(B, 'f')
Out[39]: 1

Ok, what either causes super or scans mro?

In [40]: getattr(A, 'f')
Out[40]: 1

Expected.

In [41]: object.__getattribute__(A, 'f')
Out[41]: 1

In [42]: object.__getattribute__(B, 'f')
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-42-de76df798d1d> in <module>()
----> 1 object.__getattribute__(B, 'f')

AttributeError: 'type' object has no attribute 'f'

What is getattribute without doing this getattr?

In [43]: type.__getattribute__(B, 'f')
Out[43]: 1

What?! type.__getattribute__is super, but the objectversion is not working?

In [44]: type.__getattribute__(A, 'f')
Out[44]: 1
+4
source share
1 answer

You work directly on classes. object.__getattribute__used only for instances Aand B. This is because special methods are looked up by type ; for instances, type is a class.

For classes then type: .. type:

>>> class A:
...     f = 1
... 
>>> class B(A):
...     pass
... 
>>> type(B)
<class 'type'>

used by type.__getattribute__:

>>> type.__getattribute__(B, 'f')
1

object.__getattribute__ :

>>> object.__getattribute__(B(), 'f')
1

( ), , , , MRO. object.__getattribute__. , object.__getattribute__ (, self, ) type(self).__mro__.

; type.__getattribute__ self.__mro__ ; self .

object.__getattribute__ , f B , f type(B).__mro__. type.__getattribute__, A B.__mro__, f :

>>> type(B).__mro__
(<class 'type'>, <class 'object'>)
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
+6

Source: https://habr.com/ru/post/1544055/


All Articles