I just started learning Python a few months ago, and I'm trying to understand the differences between the different __get*__
methods:
__get__
__getattr__
__getattribute__
__getitem___
And their __del*__
equivalents:
__del__
__delattr__
__delete__
__delitem__
What are the differences between these? When should I use one over the other? Is there a specific reason why most of the __get*__
methods have __set*__
equivalents, but there is no __setattribute__
?
The documentation for every method that you listed is easly reachable from the documentation index .
Anyway this may be a little extended reference:
__get__
, __set__
and __del__
are descriptors"In a nutshell, a descriptor is a way to customize what happens when you reference an attribute on a model." [official doc link]
They are well explained around, so here there are some references:
__getattr__
, __getattribute__
, __setattr__
, __delattr__
Are methods that can be defined to customize the meaning of attribute access (use of, assignment to, or deletion of x.name
) for class instances. [official doc link]
Example 1:
class Foo:
def __init__(self):
self.x = 10
def __getattr__(self, name):
return name
f = Foo()
f.x # -> 10
f.bar # -> 'bar'
Example 2:
class Foo:
def __init__(self):
self.x = 10
def __getattr__(self,name):
return name
def __getattribute__(self, name):
if name == 'bar':
raise AttributeError
return 'getattribute'
f = Foo()
f.x # -> 'getattribute'
f.baz # -> 'getattribute'
f.bar # -> 'bar'
__getitem__
, __setitem__
, __delitem__
Are methods that can be defined to implement container objects. [official doc link]
Example:
class MyColors:
def __init__(self):
self._colors = {'yellow': 1, 'red': 2, 'blue': 3}
def __getitem__(self, name):
return self._colors.get(name, 100)
colors = MyColors()
colors['yellow'] # -> 1
colors['brown'] # -> 100
I hope this is enough to give you a general idea.