2012-05-30 18 views
20

¿Cuál es la forma más fácil de crear un objeto desnudo al que pueda asignar atributos?Python simple naked objects

El caso de uso específico es: estoy realizando varias operaciones en una instancia de objeto Django, pero a veces la instancia es Ninguna (hay en la instancia). En este caso, me gustaría crear el objeto falso más simple posible para que pueda asignar valores a sus atributos (por ejemplo, myobject.foo = 'bar').

Básicamente estoy buscando el equivalente Python de este pedazo de Javascript:

myobject = {} 
myobject.foo = 'bar' 

Sé que puedo utilizar un objeto/biblioteca de simulacro para esto, pero yo estoy esperando una solución muy simple (tan simple como el Javascript anterior). ¿Hay alguna manera de crear una instancia de objeto desnudo? Algo así como:

myobject = object() 
myobject.foo = 'bar' 
+0

Eso parece bastante desnuda para mí. ¿Cuál es exactamente el umbral que desea permanecer debajo? – Karmel

+3

El código python anterior está bastante desnudo, pero desafortunadamente no funciona. – Parand

+0

Sí, eso es lo que obtengo por comentar demasiado rápido. Por supuesto :) – Karmel

Respuesta

27

Es necesario crear una clase simple en primer lugar:

class Foo(object): 
    pass 

myobject = Foo() 
myobject.foo = 'bar' 

Puede hacer que sea de una sola línea como este:

myobject = type("Foo", (object,), {})() 
myobject.foo = 'bar' 

La llamada a type funciona de forma idéntica a la declaración anterior class.

Si quieres ser realmente mínima ...

myobject = type("",(), {})() 

La clave es que la incorporada en los tipos (como list y object) no son compatibles con los atributos definidos por el usuario, por lo que necesita crear un tipo usando una declaración class o una llamada a la versión de 3 parámetros de type.

+0

Bueno, eso es muy mínimo de hecho. Lamentablemente, tampoco se puede leer, así que iré con el primer método de objeto que recomiende. Si alguien tiene una versión mínima pero legible, todavía estoy jugando ... – Parand

+0

En realidad, no tiene que heredar del objeto: 'clase Dummy(): pass' funcionará bien. –

+0

Probablemente. Me alejo de las clases de estilo antiguo en Python 2 donde sea posible. – chepner

0

Tal vez usted está buscando algo como esto:

myobject={} 
myobject['foo']='bar' 

entonces se le puede llamar como:

print myobject['foo'] 

o se puede utilizar un objeto de clase para esto:

class holder(object): 
    pass 

la n se puede usar algo como esto:

hold=holder() 
hold.myobject='bar' 
print hold.myobject 
+0

Estoy buscando específicamente usar la notación de puntos para acceder a los atributos para que el mismo código que manipula las instancias del objeto django pueda funcionar en esto, así que querría myobject.foo en lugar de myobject ['foo'] – Parand

+0

Eso es un dict en python, no un objeto. – bschlueter

1

que tendría que subclase objeto primero como esto ...

class Myobject(object): 
    pass 

myobject1 = Myobject() 
myobject1.foo = 'bar' 
2
class NakedObject(object): 
    pass 

myobject = NakedObject() 
myobject.foo = 'bar' 
0

Probablemente deberías simplemente usar un dict, según la respuesta de @ PsychicOak.

Sin embargo, si realmente desea que un objeto se puede manipular, tratar:

class FooClass(object): pass 

A continuación, puede asignar atributos de FooClass sí mismo, o en casos, como desee.

6

utilizar el módulo Bunch:

sudo pip install bunch 

Un grupo es un diccionario que permite acceder a su contenido a través de la sintaxis dict.key.

Y entonces así:

from bunch import Bunch 
b = Bunch() 
b.foo = "Bar" 


b["foo2"] = "Bar2" 
print b 
>> Bunch(foo='Bar', foo2='Bar2') 
b["foo"] = "Baz" 
print b 
>> Bunch(foo='Baz', foo2='Bar2') 
0

Por lo general prefieren crear un null object para mi clase:

class User(Model): 
    username = CharField() 
    password = CharField() 


NONE_USER = User(username='', password='') 

Entonces lo uso cuando me gustaría utilizar el objeto desnudo.

2

Vengo aquí muy tarde, pero me sorprende que nadie ha mencionado namedtuples, que cumplen este tipo de cosas:

Foo = namedtuple('Foo', ['x']) 
f = Foo(x='myattribute') 
f.x 
+0

Para usar namedtuple, debemos conocer los atributos de antemano, lo que podría no ser el caso aquí. No puede agregar atributos arbitrarios a los objetos en este caso. – aravindsagar