Quiero crear un objeto dinámico (dentro de otro objeto) en Python y luego agregarle atributos.
Lo intenté:
obj = someobject
obj.a = object()
setattr(obj.a, 'somefield', 'somevalue')
Pero esto no funcionó.
¿Algunas ideas?
editar:
Estoy configurando los atributos de un forbucle que recorre una lista de valores, por ejemplo
params = ['attr1', 'attr2', 'attr3']
obj = someobject
obj.a = object()
for p in params:
obj.a.p # where p comes from for loop variable
En el ejemplo anterior me gustaría conseguir obj.a.attr1, obj.a.attr2, obj.a.attr3.
Usé la setattrfunción porque no sabía cómo hacerlo obj.a.NAMEdesde un forbucle.
¿Cómo establecería el atributo en función del valor de pen el ejemplo anterior?
python
class
object
attributes
Juan
fuente
fuente

a = object()y lo necesitasobj.a = object(). Nuevamente, estoy hablando del ejemplo, en su código real, un objeto dentro de un objeto podría ser útil.Respuestas:
Podrías usar mi antigua receta Bunch , pero si no quieres hacer una "clase de grupo", ya existe una muy simple en Python: todas las funciones pueden tener atributos arbitrarios (incluidas las funciones lambda). Entonces, lo siguiente funciona:
Si la pérdida de claridad en comparación con la
Bunchreceta venerable está bien, es una decisión de estilo que, por supuesto, dejaré en sus manos.fuente
lambda: 23), por lo que a dichos expertos usanlambdas para este propósito presumiblemente no sentiría nada como "un hack". Personalmente, no me gusta mucholambdaPython , pero eso es en gran medida un problema de gusto personal.lambdapatrón se ajusta o no a su caso de uso puede llevarlo a darse cuenta de que algo que originalmente pensó como datos es en realidad más como una función, o, en cualquier caso, un functor.from argparse import Namespaceaunque desearía que viviera en otro lugar *, por ejemplo,collection) - nuevamente reutilizando un tipo ahora existente, solo uno mejor, y aún evitando la creación de nuevos tipos. Pero, no estaba allí entonces :-).El incorporado
objectpuede ser instanciado pero no puede tener ningún atributo establecido en él. (Ojalá pudiera, para este propósito exacto). No tiene__dict__que contener los atributos.Generalmente solo hago esto:
Cuando puedo, le doy a la
Objectclase un nombre más significativo, dependiendo de qué tipo de datos estoy poniendo.Algunas personas hacen algo diferente, donde usan una subclase
dictque permite el acceso a los atributos para obtener las teclas. (end.keylugar ded['key'])Editar : para agregar a su pregunta, usar
setattrestá bien. Simplemente no se puede usarsetattrenobject()instancias.fuente
foo = object()funciona, pero simplemente no puedes hacer nada con éltype....o lambda nunca fue mi favorito, como el vómito de texto en mi código. Pero esta idea es excelente para usar objetos para mantener propiedades. Deja el código más legible b / c cuando veo lambda. ¡Disminuyo mi lectura al 25% mientras tu camino tiene sentido! Gracias.Structcomo nombre de la clase para hacerlo más obvio. Me ahorró un montón de mecanografía["y"], ¡salud!Hay
types.SimpleNamespaceclase en Python 3.3+ :collections.namedtuple,typing.NamedTuplepodría usarse para objetos inmutables. PEP 557: las clases de datos sugieren una alternativa mutable.Para una funcionalidad más rica, puedes probar el
attrspaquete . Vea un ejemplo de uso .fuente
argparse.Namespaceclaseattrspaquete @Roel admite Python 2.7Hay algunas formas de alcanzar este objetivo. Básicamente necesitas un objeto que sea extensible.
fuente
obj.a = type('', (), {})El
mockmódulo está básicamente hecho para eso.fuente
unittest.Mockes parte de la biblioteca estándar desde Python 3.3 ( docs.python.org/3/library/unittest.mock.html )mock. Solo se siente raro para mí.Ahora puedes hacerlo (no estoy seguro si es la misma respuesta que evilpie):
fuente
Prueba el siguiente código:
fuente
También puede usar un objeto de clase directamente; crea un espacio de nombres:
fuente
como dicen los documentos :
Podrías usar una instancia de clase ficticia.
fuente
Estas soluciones son muy útiles durante las pruebas. Basándome en las respuestas de todos los demás, hago esto en Python 2.7.9 (sin el método estático obtengo un TypeError (método independiente ...):
fuente
¿Qué objetos estás usando? Solo intenté eso con una clase de muestra y funcionó bien:
Y obtuve
123la respuesta.La única situación en la que veo que esto falla es si estás probando un
setattrobjeto incorporado.Actualización: Del comentario, esta es una repetición de: ¿Por qué no puedes agregar atributos al objeto en Python?
fuente
Llegando a esto tarde en el día, pero aquí está mi pennyworth con un objeto que simplemente contiene algunas rutas útiles en una aplicación, pero puede adaptarlo para cualquier cosa donde desee un tipo de información a la que pueda acceder con getattr y notación de puntos (que es de lo que creo que se trata realmente esta pregunta):
Esto es genial porque ahora:
Por lo tanto, esto usa el objeto de función como las respuestas anteriores, pero usa la función para obtener los valores (aún puede usar en
(getattr, x_path, 'repository')lugar dex_path('repository')si lo prefiere).fuente
Si podemos determinar y agregar todos los atributos y valores juntos antes de crear el objeto anidado, entonces podríamos crear una nueva clase que tome un argumento de diccionario en la creación.
También podemos permitir argumentos de palabras clave. Ver este post .
fuente
fuente
De otra manera veo, de esta manera:
fuente
class a: passbrinda toda la potencia requerida.