Recientemente leí sobre la getattr()
función . El problema es que todavía no puedo entender la idea de su uso. Lo único que entiendo getattr()
es que getattr(li, "pop")
es lo mismo que llamar li.pop
.
No entendí cuando el libro mencionó cómo lo usas para obtener una referencia a una función sin saber su nombre hasta el tiempo de ejecución. Tal vez este soy yo un novato en programación, en general. ¿Alguien podría arrojar algo de luz sobre el tema? ¿Cuándo y cómo uso esto exactamente?
Respuestas:
getattr(object, 'x')
es completamente equivalente aobject.x
.Solo hay dos casos en los que
getattr
puede ser útil.object.x
, porque no sabe de antemano qué atributo desea (proviene de una cadena). Muy útil para la metaprogramación.object.y
levantará unAttributeError
si no hayy
. Perogetattr(object, 'y', 5)
volveremos5
.fuente
Los objetos en Python pueden tener atributos: atributos de datos y funciones para trabajar con esos (métodos). En realidad, cada objeto tiene atributos incorporados.
Por ejemplo, usted tiene un objeto
person
, que tiene varios atributos:name
,gender
, etc.Se accede a estos atributos (ya sea métodos u objetos de datos) suele escribir:
person.name
,person.gender
,person.the_method()
, etc.Pero, ¿qué sucede si no conoce el nombre del atributo al momento de escribir el programa? Por ejemplo, tiene el nombre del atributo almacenado en una variable llamada
attr_name
.Si
entonces, en lugar de escribir
puedes escribir
Alguna práctica:
getattr
se elevaráAttributeError
si el atributo con el nombre dado no existe en el objeto:Pero puede pasar un valor predeterminado como tercer argumento, que se devolverá si dicho atributo no existe:
Puede usar
getattr
junto condir
iterar sobre todos los nombres de atributos y obtener sus valores:Un uso práctico para esto sería encontrar todos los métodos cuyos nombres comiencen con ellos
test
y llamarlos .Similar a
getattr
there is,setattr
que le permite establecer un atributo de un objeto que tiene su nombre:fuente
getattr(..)
debería usarse en 2 escenarios: 1. cuando el nombre del atributo es un valor dentro de una variable (por ejemplogetattr(person, some_attr)
) y 2. cuando necesitamos usar el tercer argumento posicional para el valor predeterminado (por ejemplogetattr(person, 'age', 24)
). Si veo un escenario comogetattr(person, 'age')
este me parece que es idéntico alperson.age
que me lleva a pensar queperson.age
es más Pitónico. ¿Es eso correcto?Para mí,
getattr
es más fácil explicarlo de esta manera:Le permite llamar a métodos basados en el contenido de una cadena en lugar de escribir el nombre del método.
Por ejemplo, no puedes hacer esto:
porque x no es del tipo
builtin
, perostr
. Sin embargo, PUEDES hacer esto:Le permite conectarse dinámicamente con objetos en función de su entrada. Lo he encontrado útil cuando se trata de objetos y módulos personalizados.
fuente
Un caso de uso bastante común para
getattr
es la asignación de datos a funciones.Por ejemplo, en un marco web como Django o Pylons,
getattr
es sencillo asignar la URL de una solicitud web a la función que la va a manejar. Si observa bajo el capó de la ruta de Pylons, por ejemplo, verá que (por defecto, al menos) corta la URL de una solicitud, como:en "clientes" y "lista". Luego busca una clase de controlador llamada
CustomerController
. Suponiendo que encuentra la clase, crea una instancia de la clase y luego usagetattr
para obtener sulist
método. Luego llama a ese método y le pasa la solicitud como argumento.Una vez que comprenda esta idea, se vuelve realmente fácil ampliar la funcionalidad de una aplicación web: simplemente agregue nuevos métodos a las clases de controlador y luego cree enlaces en sus páginas que usen las URL apropiadas para esos métodos. Todo esto es posible gracias a
getattr
.fuente
Aquí hay un ejemplo rápido y sucio de cómo una clase podría disparar diferentes versiones de un método de guardar dependiendo del sistema operativo en el que se ejecute
getattr()
.Ahora usemos esta clase en un ejemplo:
fuente
Además de todas las respuestas sorprendentes aquí, hay una forma de usar
getattr
para guardar copiosas líneas de código y mantenerlo ajustado. Este pensamiento surgió después de la terrible representación del código que a veces podría ser una necesidad.Guión
Supongamos que la estructura de su directorio es la siguiente:
Y, que tiene funciones para obtener información acerca de
Thor
,Iron Man
,Doctor Strange
ensuperheroes.py
. Usted escribe muy inteligentemente las propiedades de todos ellosproperties.py
en un compactodict
y luego accede a ellos.properties.py
Ahora, supongamos que desea devolver las capacidades de cada uno de ellos a pedido
superheroes.py
. Entonces, hay funciones como... y más funciones que devuelven valores diferentes según las teclas y el superhéroe.
Con la ayuda de
getattr
, podría hacer algo como:¡Redujo considerablemente el número de líneas de código, funciones y repetición!
Ah, y por supuesto, si tiene nombres malos como
properties_of_thor
variables, se pueden hacer y acceder simplemente haciendoNOTA: Para este problema en particular, puede haber formas más inteligentes de lidiar con la situación, pero la idea es dar una idea sobre el uso
getattr
en los lugares correctos para escribir código más limpio.fuente
fuente
A veces uso
getattr(..)
para inicializar perezosamente atributos de importancia secundaria justo antes de que se usen en el código.Compare lo siguiente:
A esto:
La ventaja de la segunda forma es que
n_calls_to_plot
solo aparece alrededor del lugar en el código donde se usa. Esto es bueno para la legibilidad, porque (1) puede ver inmediatamente con qué valor comienza cuando lee cómo se usa, (2) no introduce una distracción en el__init__(..)
método, que idealmente debería ser sobre el estado conceptual de la clase , en lugar de algún contador de utilidad que solo es utilizado por uno de los métodos de la función por razones técnicas, como la optimización, y no tiene nada que ver con el significado del objeto.fuente
Con mucha frecuencia cuando estoy creando un archivo XML a partir de datos almacenados en una clase, frecuentemente recibo errores si el atributo no existe o es de tipo
None
. En este caso, mi problema no era no saber cuál era el nombre del atributo, como se indicó en su pregunta, sino que los datos se almacenaban en ese atributo.Si solía
hasattr
hacer esto, volveríaTrue
incluso si el valor del atributo fuera de tipoNone
y esto haría que miset
comando ElementTree fallara.Si el valor del atributo fuera de tipo
None
,getattr
también lo devolvería, lo que provocaría que miset
comando ElementTree fallara.Ahora uso el siguiente método para atender estos casos:
Esto es cuándo y cómo uso
getattr
.fuente
Otro uso de getattr () en la implementación de una declaración de cambio en Python. Utiliza ambos reflejos para obtener el tipo de caso.
fuente
setattr ()
Usamos setattr para agregar un atributo a nuestra instancia de clase. Pasamos la instancia de clase, el nombre del atributo y el valor.
getattr ()
Con getattr recuperamos estos valores
Por ejemplo
fuente
Creo que este ejemplo se explica por sí mismo. Ejecuta el método del primer parámetro, cuyo nombre se da en el segundo parámetro.
fuente
También está aclarando desde https://www.programiz.com/python-programming/methods/built-in/getattr
La edad es: 23
La edad es: 23
El sexo es: masculino
AttributeError: el objeto 'Persona' no tiene atributo 'sexo'
fuente
Lo he intentado en Python2.7.17
Algunos de los compañeros ya respondieron. Sin embargo, intenté llamar a getattr (obj, 'set_value') y esto no ejecutó el método set_value, así que cambié a getattr (obj, 'set_value') () -> Esto ayuda a invocar lo mismo.
Código de ejemplo:
Ejemplo 1:
fuente