¿Cómo anulo correctamente __setattr__ y __getattribute__ en las clases de estilo nuevo en Python?

Quiero anular los métodos __getattribute__ y __setattr__ mi clase Python. Mi caso de uso es el habitual: tengo algunos nombres especiales que quiero manejar y quiero el comportamiento predeterminado para cualquier otra cosa. Para __getattribute__ , parece que puedo solicitar el comportamiento predeterminado simplemente elevando AttributeError . Sin embargo, ¿cómo puedo lograr lo mismo en __setattr__ ? Aquí hay un ejemplo trivial, implementando una clase con campos inmutables “A”, “B” y “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? ??? 

¿Qué va en lugar de los signos de interrogación? Con las clases de estilo antiguo, la respuesta fue aparentemente self.__dict__[name] = value , pero la documentación indica que esto es incorrecto para las clases de estilo nuevo.

Sus

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

en Python 2, o

 super().__setattr__(name, value) 

en Python 3.

Además, boost AttributeError no es la forma en que __getattribute__ al comportamiento predeterminado para __getattribute__ . Usted vuelve a la predeterminada con

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

en Python 2 o

 return super().__getattribute__(name) 

en Python 3.

El aumento de AttributeError omite el manejo predeterminado y va a __getattr__ , o simplemente produce un AttributeError en el código de llamada si no hay __getattr__ .

Consulte la documentación sobre Personalización del acceso a atributos .

SomeSuperclass.__setattr__(self, name, value) ?