visual tools mac full for development class python komodo

class - tools - python ide mac



¿Crear propiedades de instancia de clase de un diccionario? (6)

Podría hacer una subclase de dict que permita la búsqueda de atributos para las claves:

class AttributeDict(dict): def __getattr__(self, name): return self[name] q = AttributeDict({ ''Field1'' : 3000, ''Field2'' : 6000, ''RandomField'' : 5000 }) print q.Field1 print q.Field2 print q.RandomField

Si intentas buscar un atributo que ya tiene dict (digamos keys o get ), obtendrás ese atributo de clase dict (un método). Si la clave solicitada no existe en la clase dict , se __getattr__ método __getattr__ y se realizará la búsqueda de claves.

Importación desde un archivo CSV y obtengo datos aproximadamente en el formato

{ ''Field1'' : 3000, ''Field2'' : 6000, ''RandomField'' : 5000 }

Los nombres de los campos son dinámicos. (Bueno, son dinámicos porque puede haber más de Field1 y Field2, pero sé que Field1 y Field2 siempre estarán allí.

Me gustaría poder pasar este diccionario a mi clase allMyFields para que pueda acceder a los datos anteriores como propiedades.

class allMyFields: # I think I need to include these to allow hinting in Komodo. I think. self.Field1 = None self.Field2 = None def __init__(self,dictionary): for k,v in dictionary.items(): self.k = v #of course, this doesn''t work. I''ve ended up doing this instead #self.data[k] = v #but it''s not the way I want to access the data. q = { ''Field1'' : 3000, ''Field2'' : 6000, ''RandomField'' : 5000 } instance = allMyFields(q) # Ideally I could do this. print q.Field1

¿Alguna sugerencia? En cuanto a por qué, me gustaría poder aprovechar la sugerencia del código e importar los datos en un diccionario llamado data tal como he estado haciendo, no me permite nada de eso.

(Dado que los nombres de las variables no se resuelven hasta el tiempo de ejecución, todavía tendré que arrojarle un hueso a Komodo, creo que el self.Field1 = None debería ser suficiente).

Entonces, ¿cómo hago lo que quiero? ¿O estoy ladrando a un árbol mal diseñado, no python?


Puedes usar setattr (ten cuidado: no todas las cadenas son un nombre de atributo válido):

>>> class AllMyFields: ... def __init__(self, dictionary): ... for k, v in dictionary.items(): ... setattr(self, k, v) ... >>> o = AllMyFields({''a'': 1, ''b'': 2}) >>> o.a 1

Editar: déjame explicarte la diferencia entre el código anterior y la respuesta de SilentGhost . El fragmento de código anterior crea una clase de los atributos de instancia que se basan en un diccionario determinado. El código de SilentGhost crea una clase cuyos atributos de clase se basan en un diccionario determinado.

Dependiendo de su situación específica, cualquiera de estas soluciones puede ser más adecuada. ¿Crees que puedes crear una o más instancias de clase? Si la respuesta es una, también puedes omitir la creación de objetos por completo y solo construir el tipo (y así ir con la respuesta de SilentGhost).


También puede usar dict.update lugar de hacer un bucle manual sobre los items (y si está iteritems , iteritems es mejor).

class allMyFields(object): # note: you cannot (and don''t have to) use self here Field1 = None Field2 = None def __init__(self, dictionary): self.__dict__.update(dictionary) q = { ''Field1'' : 3000, ''Field2'' : 6000, ''RandomField'' : 5000 } instance = allMyFields(q) print instance.Field1 # => 3000 print instance.Field2 # => 6000 print instance.RandomField # => 5000


Usa setattr para la forma bonita. La forma rápida y sucia es actualizar el diccionario interno de la instancia:

>>> class A(object): ... pass ... >>> a = A() >>> a.__dict__.update({"foo": 1, "bar": 2}) >>> a.foo 1 >>> a.bar 2 >>>


Usando tuplas con nombre (Python 2.6):

>>> from collections import namedtuple >>> the_dict = {''Field1'': 3, ''Field2'': ''b'', ''foo'': 4.9} >>> fields = '' ''.join(the_dict.keys()) >>> AllMyFields = namedtuple(''AllMyFields'', fields) >>> instance = AllMyFields(**the_dict) >>> print instance.Field1, instance.Field2, instance.foo 3 b 4.9


>>> q = { ''Field1'' : 3000, ''Field2'' : 6000, ''RandomField'' : 5000 } >>> q = type(''allMyFields'', (object,), q) >>> q.Field1 3000

los documentos para type explican bien lo que está sucediendo aquí (ver uso como constructor).

editar : en caso de que necesite variables de instancia, lo siguiente también funciona:

>>> a = q() # first instance >>> a.Field1 3000 >>> a.Field1 = 1 >>> a.Field1 1 >>> q().Field1 # second instance 3000