Some questions about __getattr__ and __getattribute__?

First demo:

class B:
    def __init__(self):
        self.name = '234'
    # def __getattribute__(self, name):
    #     print('getattr')
    def __getattr__(self, name):    
        print('get')
    def __setattr__(self, name, value):
        print('set')
    def __delattr__(self, name):
        print('del')


b = B()
print(b.__dict__)
b.name

b.__dict__- {}, but the second demo:

class B:
    def __init__(self):
        self.name = '234'
    def __getattribute__(self, name):
        print('getattr')
    def __getattr__(self, name):
        print('get')
    def __setattr__(self, name, value):
        print('set')
    def __delattr__(self, name):
        print('del')


b = B()
print(b.__dict__)
b.name

b.__dict__ Nonewhy? And it b.__dict__causes __getattribute__, but does not cause __getattr__, does it mean that it __getattribute__will impede the call __getattr__?

+4
source share
1 answer

Methods __getattribute__, __setattr__and __delattr__are called to access all attributes (retrieve, install, and delete). __getattr__, on the other hand, is called only for missing attributes; it is usually not implemented, but if it then __getattribute__calls it, if it could not otherwise find the attribute, or if it AttributeErrorwas raised __getattribute__.

, , print return None ( return). __dict__ - , __getattribute__ None __getattr__ AttributeError.

:

object.__getattr__(self, name)
, (.. self).

object.__getattribute__(self, name)
. __getattr__(), , __getattribute__() AttributeError.

( ).

( super().__getattribute__), AttributeError:

>>> class B:
...     def __init__(self):
...         self.name = '234'
...     def __getattribute__(self, name):
...         print('getattr')
...         return super().__getattribute__(name)
...     def __getattr__(self, name):
...         print('get')
...     def __setattr__(self, name, value):
...         print('set')
...     def __delattr__(self, name):
...         print('del')
...
>>> b = B()
set
>>> b.__dict__
getattr
{}
>>> b.name
getattr
get
>>> class B:
...     def __init__(self):
...         self.name = '234'
...     def __getattribute__(self, name):
...         print('getattr')
...         raise AttributeError(name)
...     def __getattr__(self, name):
...         print('get')
...     def __setattr__(self, name, value):
...         print('set')
...     def __delattr__(self, name):
...         print('del')
...
>>> b = B()
set
>>> b.__dict__
getattr
get
>>> b.name
getattr
get

, , super().__getattribute__, __dict__. AttributeError , __getattr__, None.

+5

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


All Articles