Как правильно переопределить __setattr__ и __getattribute__ в классах нового стиля в Python? - PullRequest
38 голосов
/ 12 августа 2011

Я хочу переопределить методы __getattribute__ и __setattr__ моего класса Python.Мой вариант использования обычный: у меня есть несколько специальных имен, которые я хочу обработать, и я хочу поведение по умолчанию для всего остального.Для __getattribute__ кажется, что я могу запросить поведение по умолчанию, просто подняв AttributeError.Тем не менее, как я могу добиться того же в __setattr__?Вот тривиальный пример реализации класса с неизменяемыми полями «A», «B» и «C».

class ABCImmutable(SomeSuperclass):
    def __getattribute__(self, name):
        if name in ("A", "B", "C"):
            return "Immutable value of %s" % name
        else:
            # This should trigger the default behavior for any other
            # attribute name.
            raise AttributeError()

    def __setattr__(self, name, value):
        if name in ("A", "B", "C"):
            raise AttributeError("%s is an immutable attribute.")
        else:
            # How do I request the default behavior?
            ???

Что стоит вместо знаков вопроса?С классами старого стиля ответ был, очевидно, self.__dict__[name] = value, но документация указывает, что это неправильно для классов нового стиля.

Ответы [ 2 ]

41 голосов
/ 12 августа 2011

Это

super(ABCImmutable, self).__setattr__(name, value)

в Python 2 или

super().__setattr__(name, value)

в Python 3.

Кроме того, повышение AttributeError равно , а не как вы вернетесь к поведению по умолчанию для __getattribute__.Вы вернетесь к значениям по умолчанию:

return super(ABCImmutable, self).__getattribute__(name)

на Python 2 или

return super().__getattribute__(name)

на Python 3.

Raising AttributeError пропускает обработку по умолчанию и переходит к__getattr__ или просто выдает AttributeError в коде вызова, если его нет __getattr__.

См. Документацию по Настройка доступа к атрибутам .

6 голосов
/ 12 августа 2011

SomeSuperclass.__setattr__(self, name, value)?

...