Puedo usar esto cuando necesito varios objetos con diferentes atributos:

class struct(object):
   def __init__(self,*args,**kwargs):
      for key,val in kwargs.items():
         setattr(self,key,val)

Pero me pregunto si no hay un incorporado ya?

2
Geo 13 nov. 2009 a las 20:31

3 respuestas

La mejor respuesta

A menos que no entienda su pregunta, ¿no es para esto que usamos un dict? Claro, es notoriamente ligeramente diferente, pero los atributos de un objeto aún se almacenan internamente en un dict (es decir, __dict__). Es una cuestión de notación.

Pero, si insiste, esta es una forma de hacerlo:

>>> class struct(dict):
...     def __getattribute__(self, key):
...         return self[key]
... 
>>> s = struct(a=5, b=7)
>>> s.a
5

Tenga en cuenta que estoy usando __getattribute__ en lugar de __getattr__. La razón de esto es que, de lo contrario, no podemos almacenar atributos con nombres como get y keys, ya que estos son métodos definidos por dict.

La solución de SilentGhost es probablemente más eficiente y funciona igual de bien, sin recurrir al uso de __getattribute__. El código luego se convierte en:

>>> def struct(**kwargs):
...     return type('Struct', (object,), kwargs)
... 
>>> s = struct(a=5, b=7)
>>> s.a
5
9
Community 23 may. 2017 a las 12:19

Me he preguntado lo mismo. Disfruto de la comodidad de x.foo en lugar de x["foo"]; un solo punto es mucho más fácil de escribir (y corregir) que todos los [""].

La ventaja de un dict es que cualquier cosa puede ser una clave. (Bueno, cualquier cosa que se pueda cambiar.) Pero cuando tengo un montón de valores que quiero agrupar, los nombres clave que elijo son identificadores válidos de todos modos.

Aquí está la versión básica de esta idea:

class struct(object):
    pass

x = struct()
x.foo = 1

Mientras tenga tantos problemas, también podría agregar el __init__() que maneja kwargs para una inicialización conveniente. Pero soy vago y esperaba algo incorporado.

Intenté esto, que no funciona:

x = object()
x.foo = 1   # raises AttributeError exception

Le pregunté al respecto, y la respuesta que obtuve fue que object es la raíz de todos los tipos en Python; Es lo más pequeño posible. Si pudiera actuar como una instancia de clase, con su propio atributo __dict__, entonces cada objeto creado en Python necesitaría un __dict__ adjunto.

Me hubiera gustado ver struct agregado como incorporado en Python 3.x. Pero entiendo por qué no fue así: mantener el lenguaje pequeño y limpio es un objetivo digno, y esta característica es trivialmente fácil de codificar usted mismo.

3
steveha 13 nov. 2009 a las 19:31

No estoy seguro de por qué no estás usando un diccionario para esto.

x = {}
x.update([(1, 2), (3, 4), (5, 6)])
print x

Resultado

{1: 2, 3: 4, 5: 6}

O

x.update(a=2, b=4, c=6)

Resultados en

{'a': 2, 'c': 6, 'b': 4}
3
Bryan McLemore 13 nov. 2009 a las 17:40