¿Cómo disputo las búsquedas de python: make.up.a.dot.separated.name.and.use.it.until.destroyed = 777

StackOverflow https://stackoverflow.com/questions/1602745

  •  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
¿Fue útil?

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ón AttributeError .

     

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 ejecutar self.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) .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top