¿Cómo disputo las búsquedas de python: make.up.a.dot.separated.name.and.use.it.until.destroyed = 777
-
05-07-2019 - |
Pregunta
Soy un novato de Python con una picazón muy particular para experimentar con el proceso de búsqueda de nombres de puntos de Python. ¿Cómo puedo codificar una clase o función en " make.py " para que estas declaraciones de asignación funcionen correctamente?
import make
make.a.dot.separated.name = 666
make.something.else.up = 123
make.anything.i.want = 777
Solución
#!/usr/bin/env python
class Make:
def __getattr__(self, name):
self.__dict__[name] = Make()
return self.__dict__[name]
make = Make()
make.a.dot.separated.name = 666
make.anything.i.want = 777
print make.a.dot.separated.name
print make.anything.i.want
Se llama al método especial __getattr__
cuando no se encuentra un valor con nombre. La línea make.anything.i.want
termina haciendo el equivalente de:
m1 = make.anything # calls make.__getattr__("anything")
m2 = m1.i # calls m1.__getattr__("i")
m2.want = 777
La implementación anterior utiliza estas llamadas a __getattr__
para crear una cadena de objetos Make
cada vez que se accede a una propiedad desconocida. Esto permite anidar los accesos de puntos de forma arbitraria hasta la asignación final, momento en el que se asigna un valor real.
Documentación de Python - personalizando el acceso a los atributos :
object .__ getattr __ (self, name)
Se llama cuando una búsqueda de atributo no ha encontrado el atributo en los lugares habituales (es decir, no es un atributo de instancia ni se encuentra en el árbol de clases para
self
).name
es el nombre del atributo. Este método debe devolver el valor de atributo (calculado) o generar una excepciónAttributeError
.Tenga en cuenta que si el atributo se encuentra a través del mecanismo normal, no se llama a
__getattr __ ()
. (Esta es una asimetría intencional entre__getattr __ ()
y__setattr __ ()
.) Esto se hace por razones de eficiencia y porque, de lo contrario,__getattr __ ()
No tendría forma de acceder a otros atributos de la instancia. Tenga en cuenta que, al menos para las variables de instancia, puede falsificar el control total al no insertar ningún valor en el diccionario de atributos de la instancia (sino en su lugar, insertarlo en otro objeto). Consulte el método__getattribute __ ()
a continuación para obtener una manera de obtener el control total en las clases de nuevo estilo.
object .__ setattr __ (self, name, value)
Se llama cuando se intenta una asignación de atributo. Esto se llama en lugar del mecanismo normal (es decir, almacenar el valor en el diccionario de instancias).
name
es el nombre del atributo,value
es el valor que se le asignará.Si
__setattr __ ()
quiere asignar a un atributo de instancia, no debería simplemente ejecutarself.name = value
& # 8212; Esto causaría una llamada recursiva a sí mismo. En su lugar, debe insertar el valor en el diccionario de atributos de instancia, por ejemplo,self .__ dict __ [nombre] = valor
. Para las clases de nuevo estilo, en lugar de acceder al diccionario de instancia, debe llamar al método de la clase base con el mismo nombre, por ejemplo,object .__ setattr __ (self, name, value)
.