Как правильно переопределить setattr и getattribute в классах нового стиля в Python?

Я хочу переопределить класс Python __getattribute__ и __setattr__ методы. Мой вариант использования обычный: у меня есть несколько специальных имен, которые я хочу обработать, и я хочу поведение по умолчанию для чего-либо еще. Для __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 ответов


это

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

в Python 2, или

super().__setattr__(name, value)

в Python 3.

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

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

на Python 2 или

return super().__getattribute__(name)

на Python 3.

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

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


SomeSuperclass.__setattr__(self, name, value) ?