Cómo convertir una cadena en un subatributo de clase con Python
Frecuentes
Visto 3,695 equipos
5
Sé que puedo obtener los atributos de una Clase con una cadena como esta:
object.attribute = 'foo'
x = 'attribute'
getattr(object, x)
>>> 'foo'
¿Hay alguna manera de "profundizar" en los atributos del objeto con una cadena? En otras palabras, si mi objeto contiene otro objeto, ¿cómo puedo obtener los atributos del subobjeto con una cadena? Por ejemplo:
object.object.attribute
3 Respuestas
12
El operator.attrgetter
función hace esto:
class Foo: pass
f = Foo()
f.bar = Foo()
f.bar.baz = Foo()
f.bar.baz.quux = "Found me!"
import operator
print operator.attrgetter("bar.baz.quux")(f) # prints "Found me!"
Respondido 04 Jul 12, 04:07
6
Me encanta la receta dada en este aquí (aunque en realidad el comentario es aún mejor)
Ejemplo tomado de la respuesta de Claudiu (que también es genial):
class Foo: pass
f = Foo()
f.bar = Foo()
f.bar.baz = Foo()
f.bar.baz.quux = "Found me!"
Un getattr recursivo que sigue a los puntos:
>>> rgetattr = lambda o,a: reduce(getattr, a.split('.'), o)
>>> rgetattr(f, 'bar.baz.quux')
'Found me!'
La versión no lambda es:
def rgetattr(obj, attr):
return reduce(getattr, attr.split('.'), obj)
Respondido 04 Jul 12, 04:07
4
>>> class Foo: pass
>>> f = Foo()
>>> f.bar = Foo()
>>> f.bar.baz = Foo()
>>> f.bar.baz.quux = "Found me!"
>>> getattr(f, 'bar')
<__main__.Foo instance at 0x01EC5918>
>>> getattr(getattr(f, 'bar'), 'baz')
<__main__.Foo instance at 0x01EC5A30>
>>> getattr(getattr(getattr(f, 'bar'), 'baz'), 'quux')
'Found me!'
EDITAR: Hecho como un método simple:
>>> def dynamic_lookup(obj, dot_attrs):
attr_list = dot_attrs.split(".")
while attr_list:
obj = getattr(obj, attr_list.pop(0))
return obj
>>> f
<__main__.Foo instance at 0x01EC50A8>
>>> dynamic_lookup(f, 'bar.baz.quux')
'Found me!'
Fácilmente adaptable para tomar una lista de cadenas (tomar attr_list
directamente en lugar de dot_attrs
), pero pensé que el .
la notación como una cadena se vería mejor...
Respondido 04 Jul 12, 04:07
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas python class attributes or haz tu propia pregunta.
¡DECIR AH! olvidé el
attrgetter
sigue la notación de puntos - jdiAún mejor, pero gracias de todos modos @jdi... Aprendí más sobre lambdas de tu respuesta. - MFB
@MFB: No te preocupes. La respuesta de Ned es mejor ya que es una versión stdlib de lo mismo que también es más rápida. - jdi