Каковы различия между методами Python "__get * __" и "_del * __"? - PullRequest
24 голосов
/ 29 января 2012

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

__get__
__getattr__
__getattribute__
__getitem___

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

__del__
__delattr__
__delete__
__delitem__

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

1 Ответ

32 голосов
/ 29 января 2012

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

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

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

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

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

__getattr__, __getattribute__, __setattr__, __delattr__

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

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

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

Пример: * 1 066 *

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

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

...