subclases privados poo otra metodo llamar herencia ejemplos clases clase atributos python class object attributes

python - privados - ¿Cómo puedo crear un objeto y agregarle atributos?



self python 3 (16)

¿Qué objetos estás usando? Solo probé eso con una clase de muestra y funcionó bien:

class MyClass: i = 123456 def f(self): return "hello world" b = MyClass() b.c = MyClass() setattr(b.c, ''test'', 123) b.c.test

Y tengo 123 como respuesta.

La única situación en la que veo que este fallo es si estás probando un setattr en un objeto incorporado.

Actualización: Del comentario, esto es una repetición de: ¿Por qué no puedes agregar atributos al objeto en Python?

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 bucle for 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 obtendría obj.a.attr1 , obj.a.attr2 , obj.a.attr3 .

Utilicé la función setattr porque no sabía cómo hacer obj.a.NAME desde un bucle for .

¿Cómo establecería el atributo según el valor de p en el ejemplo anterior?


Ahora puedes hacerlo (no estoy seguro de si es la misma respuesta que evilpie):

MyObject = type(''MyObject'', (object,), {}) obj = MyObject() obj.value = 42


De otra manera veo, de esta manera:

import maya.cmds def getData(objets=None, attrs=None): di = {} for obj in objets: name = str(obj) di[name]=[] for at in attrs: di[name].append(cmds.getAttr(name+''.''+at)[0]) return di acns=cmds.ls(''L_vest_*_'',type=''aimConstraint'') attrs=[''offset'',''aimVector'',''upVector'',''worldUpVector''] getData(acns,attrs)


El object incorporado puede ser instanciado pero no puede tener ningún atributo establecido en él. (Ojalá pudiera, para este propósito exacto). No tiene un __dict__ para mantener los atributos.

Generalmente solo hago esto:

class Object(object): pass a = Object() a.somefield = somevalue

Cuando puedo, le doy a la clase Object un nombre más significativo, dependiendo de qué tipo de datos estoy ingresando.

Algunas personas hacen una cosa diferente, donde usan una subclase de dict que permite el acceso de atributos para obtener las claves. ( d.key lugar de d[''key''] )

Editar : Para agregar a su pregunta, usar setattr está bien. Simplemente no puede usar setattr en setattr de object() .

params = [''attr1'', ''attr2'', ''attr3''] for p in params: setattr(obj.a, p, value)


El módulo mock está hecho básicamente para eso.

import mock obj = mock.Mock() obj.a = 5


Está todo en los docs .

TLDR: necesitas hacer valer la propiedad return_value del simulacro, el resto es ''Magic''.

Ejemplo:

SomeConstructor = MagicMock() SomeConstructor.return_value. / some_class_method.assert_called_once_with(''cool!'') SomeConstructor.return_value. / some_inner_property. / some_inner_method.assert_called_once_with(''super cool!'')


Estas soluciones son muy útiles durante las pruebas. Sobre la base de 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 no vinculado ...):

In [11]: auth = type('''', (), {}) In [12]: auth.func = staticmethod(lambda i: i * 2) In [13]: auth.func(2) Out[13]: 4



Hay algunas maneras de alcanzar este objetivo. Básicamente necesitas un objeto que sea extensible.

obj.a = type(''Test'', (object,), {}) obj.a.b = ''fun'' obj.b = lambda:None class Test: pass obj.c = Test()


Llegando a esta hora avanzada, pero aquí está mi pennyworth con un objeto que por casualidad contiene algunas rutas útiles en una aplicación, pero puede adaptarlo para cualquier cosa en la que desee una cierta cantidad de información a la que pueda acceder con getattr y la notación de puntos. (que es de lo que creo que se trata realmente esta pregunta):

import os def x_path(path_name): return getattr(x_path, path_name) x_path.root = ''/home/x'' for name in [''repository'', ''caches'', ''projects'']: setattr(x_path, name, os.path.join(x_path.root, name))

Esto es genial porque ahora:

In [1]: x_path.projects Out[1]: ''/home/x/projects'' In [2]: x_path(''caches'') Out[2]: ''/home/x/caches''

Por lo tanto, utiliza el objeto de función como las respuestas anteriores, pero usa la función para obtener los valores (aún puede usar (getattr, x_path, ''repository'') lugar de x_path(''repository'') si lo prefiere).


Podría usar mi antigua receta de Bunch , pero si no desea crear una "clase de manojo", ya existe una muy simple en Python: todas las funciones pueden tener atributos arbitrarios (incluidas las funciones lambda). Así, los siguientes trabajos:

obj = someobject obj.a = lambda: None setattr(obj.a, ''somefield'', ''somevalue'')

Si la pérdida de claridad en comparación con la venerable receta de Bunch está bien, es una decisión de estilo que, por supuesto, le dejaré a usted.


Pruebe el siguiente código:

$ python >>> class Container(object): ... pass ... >>> x = Container() >>> x.a = 10 >>> x.b = 20 >>> x.banana = 100 >>> x.a, x.b, x.banana (10, 20, 100) >>> dir(x) [''__class__'', ''__delattr__'', ''__dict__'', ''__doc__'', ''__format__'', ''__getattribute__'', ''__hash__'', ''__init__'', ''__module__'', ''__new__'', ''__reduce__'', ''__reduce_ex__'', ''__repr__'', ''__setattr__'', ''__sizeof__'', ''__str__'', ''__subclasshook__'', ''__weakref__'', ''a'', ''b'', ''banana'']


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.

# python 2.7 class NestedObject(): def __init__(self, initial_attrs): for key in initial_attrs: setattr(self, key, initial_attrs[key]) obj = someobject attributes = { ''attr1'': ''val1'', ''attr2'': ''val2'', ''attr3'': ''val3'' } obj.a = NestedObject(attributes) >>> obj.a.attr1 ''val1'' >>> obj.a.attr2 ''val2'' >>> obj.a.attr3 ''val3''

También podemos permitir argumentos de palabras clave. Ver este post

class NestedObject(object): def __init__(self, *initial_attrs, **kwargs): for dictionary in initial_attrs: for key in dictionary: setattr(self, key, dictionary[key]) for key in kwargs: setattr(self, key, kwargs[key]) obj.a = NestedObject(attr1=''val1'', attr2=''val2'', attr3= ''val3'')


También puedes usar un objeto de clase directamente; crea un espacio de nombres:

class a: pass a.somefield1 = ''somevalue1'' setattr(a, ''somefield2'', ''somevalue2'')


como dicen los doctores :

Nota : el object no tiene un __dict__ , por lo que no puede asignar atributos arbitrarios a una instancia de la clase de object .

Puedes usar una instancia de clase ficticia.


di = {} for x in range(20): name = ''_id%s'' % x di[name] = type(name, (object), {}) setattr(di[name], "attr", "value")