Подтвердить что ты не робот

Каковы различия между методами Python "__get * __" и "_del * __"?

Я только начал изучать Python несколько месяцев назад, и я пытаюсь понять различия между различными методами __get*__:

__get__
__getattr__
__getattribute__
__getitem___

И их эквиваленты __del*__:

__del__
__delattr__
__delete__
__delitem__

В чем разница между ними? Когда я должен использовать один над другим? Существует ли конкретная причина, по которой большинство методов __get*__ имеют эквиваленты __set*__, но нет __setattribute__?

4b9b3361

Ответ 1

Документация для каждого выбранного вами метода легко достижима из документационного индекса.

В любом случае это может быть немного расширенной ссылкой:

__get__, __set__ и __del__ являются дескрипторами

"В двух словах дескриптор - это способ настройки того, что происходит, когда вы ссылаетесь на атрибут на модели". [официальная ссылка doc]

Они хорошо объясняются вокруг, поэтому здесь есть несколько ссылок:

__getattr__, __getattribute__, __setattr__, __delattr__

Можно ли определить методы, позволяющие настроить значение доступа к атрибутам (использование, назначение или удаление x.name) для экземпляров класса. [официальная ссылка doc]

Пример 1:

class Foo:
    def __init__(self):
        self.x = 10
    def __getattr__(self, name):
        return name

f = Foo()
f.x    # -> 10
f.bar   # -> 'bar'

Пример 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__

Можно ли определить методы для реализации объектов контейнера. [официальная ссылка doc]

Пример:

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

Надеюсь, этого достаточно, чтобы дать вам общую идею.