Quiero anular el acceso a una variable en una clase, pero devolver todas las demás normalmente. ¿Cómo logro esto con __getattribute__?
Intenté lo siguiente (que también debería ilustrar lo que estoy tratando de hacer) pero obtengo un error de recursividad:
class D(object):
def __init__(self):
self.test=20
self.test2=21
def __getattribute__(self,name):
if name=='test':
return 0.
else:
return self.__dict__[name]
>>> print D().test
0.0
>>> print D().test2
...
RuntimeError: maximum recursion depth exceeded in cmp

super(D, self).__getattribute__(name)super().__getattribute__(name)en Python 3.En realidad, creo que desea utilizar el
__getattr__método especial en su lugar.Cita de los documentos de Python:
Nota: para que esto funcione, la instancia no debe tener un
testatributo, por lo que la líneaself.test=20debe eliminarse.fuente
__getattr__portestsería inútil, ya que siempre lo encontraría "en los lugares habituales".Referencia del lenguaje Python:
Sentido:
Estás pidiendo un atributo llamado
__dict__. Como es un atributo,__getattribute__se llama para buscar__dict__qué llamadas__getattribute__qué llamadas ... yada yada yadaEl uso de las clases base
__getattribute__ayuda a encontrar el atributo real.fuente
¿Estás seguro de que quieres usar
__getattribute__? ¿Qué estás tratando de lograr realmente?La forma más sencilla de hacer lo que pide es:
o:
Editar:
Dtenga en cuenta que una instancia de tendría diferentes valores detesten cada caso. En el primer casod.testsería 20, en el segundo sería 0. Dejaré que usted averigüe por qué.Edit2: Greg señaló que el ejemplo 2 fallará porque la propiedad es de solo lectura y el
__init__método intentó establecerla en 20. Un ejemplo más completo sería:Obviamente, como clase, esto es casi completamente inútil, pero te da una idea para seguir adelante.
fuente
Aquí hay una versión más confiable:
Llama al método __ getattribute __ desde la clase principal, y eventualmente regresa al objeto. __ getattribute __ método si otros ancestros no lo anulan.
fuente
Se llama antes de la búsqueda de puntos normal. Si sube
AttributeError, llamamos__getattr__.El uso de este método es bastante raro. Solo hay dos definiciones en la biblioteca estándar:
Mejores prácticas
La forma correcta de controlar mediante programación el acceso a un solo atributo es con
property. La claseDdebe escribirse de la siguiente manera (con el establecedor y el eliminador opcionalmente para replicar el comportamiento previsto aparente):Y uso:
Una propiedad es un descriptor de datos, por lo que es lo primero que se busca en el algoritmo de búsqueda de puntos normal.
Opciones para
__getattribute__Tiene varias opciones si es absolutamente necesario implementar la búsqueda para cada atributo a través de
__getattribute__.AttributeError, haciendo__getattr__que se llame (si se implementa)superpara llamar a laobjectimplementación de los padres (probablemente )__getattr__Por ejemplo:
Lo que originalmente querías.
Y este ejemplo muestra cómo podría hacer lo que originalmente quería:
Y se comportará así:
Revisión de código
Tu código con comentarios. Tiene una búsqueda punteada de sí mismo en
__getattribute__. Es por eso que obtiene un error de recursividad. Puede verificar si el nombre es"__dict__"y usarsuperpara una solución alternativa, pero eso no cubre__slots__. Dejaré eso como un ejercicio para el lector.fuente