Быстрый в изучении - мощный в программировании
>> Telegram ЧАТ для Python Программистов

Свободное общение и помощь советом и решением проблем с кодом! Заходите в наш TELEGRAM ЧАТ!

>> Python Форум Помощи!

Мы создали форум где отвечаем на все вопросы связанные с языком программирования Python. Ждем вас там!

>> Python Канал в Telegram

Обучающие статьи, видео и новости из мира Python. Подпишитесь на наш TELEGRAM КАНАЛ!

Сравнение методов __getattr__ и __getattribute__ Python

18 октября 2015 г. Archy Просмотров: 21258 RSS 1

Чтобы обобщить различия между методами __getattr__ и __getattribute__, в следующем примере используются оба метода для реализации доступа к трем атрибутам, в числе которых: attr1 - атрибут класса, attr2 - атрибут экземпляра и attr3 - виртуальный атрибут, значение которого вычисляется при обращении к нему:

class GetAttr:
    attr1 = 1
    def __init__(self):
        self.attr2 = 2
    def __getattr__(self, attr):   # Только для неопределенных атрибутов
        print('get: ' + attr)      # Не attr1: наследуется от класса
        return 3                   # Не attr2: хранится в экземпляре
    
X = GetAttr()
print(X.attr1)
print(X.attr2)
print(X.attr3)
print('-' * 40)
class GetAttribute(object):
    attr1 = 1
    def __init__(self):
        self.attr2 = 2
    def __getattribute__(self, attr):  # Вызывается всеми операциями присваивания
        print('get: ' + attr)          # Для предотвращения зацикливания используется суперкласс
        if attr == 'attr3':
            return 3
        else:
            return object.__getattribute__(self, attr)
        
X = GetAttribute()
print(X.attr1)
print(X.attr2)
print(X.attr3)

Если запустить этот пример, можно будет увидеть, что версия на основе метода __getattr__ перехватывает только попытки обращения к атрибуту attr3, потому что это единственный неопределенный аргумент.

С другой стороны, версия на основе метода __getattribute__ перехватывает все попытки чтения значений атрибутов и для получения значений неуправляемых атрибутов должна вызывать метод суперкласса, чтобы избежать зацикливания:

1
2
get: attr3
3
----------------------------------------
get: attr1
1
get: attr2
2
get: attr3
3

Несмотря на то, что метод __getattribute__ перехватывает больше операций обращения к атрибутам, чем метод __getattr__, тем не менее, на практике они оказываются лишь вариациями на одну тему - если атрибуты физически не сохраняются в памяти, эти два метода дают один и тот же эффект.

Комментариев: 1
  1. Аноним | 2018-04-25 в 18:04:36

    77