Tenga en cuenta que la mejor práctica en Python 2.7 es usar clases de estilo nuevo (no necesarias con Python 3), es decir
class Foo(object):
...
Además, hay una diferencia entre un 'objeto' y una 'clase'. Para construir un diccionario a partir de un objeto arbitrario , es suficiente usarlo __dict__
. Por lo general, declarará sus métodos a nivel de clase y sus atributos a nivel de instancia, por lo que __dict__
debería estar bien. Por ejemplo:
>>> class A(object):
... def __init__(self):
... self.b = 1
... self.c = 2
... def do_nothing(self):
... pass
...
>>> a = A()
>>> a.__dict__
{'c': 2, 'b': 1}
Un mejor enfoque (sugerido por Robert en los comentarios) es la vars
función incorporada :
>>> vars(a)
{'c': 2, 'b': 1}
Alternativamente, dependiendo de lo que quieras hacer, puede ser bueno heredar de dict
. Entonces su clase ya es un diccionario, y si lo desea, puede anular getattr
y / o setattr
llamar y establecer el dict. Por ejemplo:
class Foo(dict):
def __init__(self):
pass
def __getattr__(self, attr):
return self[attr]
# etc...
__dict__
no funcionará si el objeto está usando ranuras (o definido en un módulo C).vars(a)
hacer esto? Para mí es preferible invocar__dict__
directamente.__getattr__ = dict.__getitem__
para replicar exactamente el comportamiento, entonces también querría__setattr__ = dict.__setitem__
y__delattr__ = dict.__delitem__
para completar.En lugar de
x.__dict__
, en realidad es más pitónico de usarvars(x)
.fuente
MyClass(**my_dict)
, suponiendo que haya definido un constructor con parámetros que reflejen los atributos de la clase. No es necesario acceder a atributos privados o anular dict.vars
función e introducir funcionalidad adicional sin cambiar el objeto en sí.__slots__
.vars
, es decir, devolver un equivalente de las__dict__
clases "ranuradas". Por ahora, se puede emular agregando una__dict__
propiedad que devuelve{x: getattr(self, x) for x in self.__slots__}
(aunque no estoy seguro si eso afecta el rendimiento o el comportamiento de alguna manera).El
dir
builtin le dará todos los atributos del objeto, incluidos métodos especiales como__str__
,__dict__
y un montón de otros que probablemente no desee. Pero puedes hacer algo como:Entonces, puede extender esto para devolver solo atributos de datos y no métodos, definiendo su
props
función de esta manera:fuente
ismethod
no atrapa funciones. Ejemplo:inspect.ismethod(str.upper)
.inspect.isfunction
Sin embargo, no es mucho más útil. No estoy seguro de cómo abordar esto de inmediato.Me decidí con una combinación de ambas respuestas:
fuente
staticmethod
? No escallable
.Pensé que me tomaría un tiempo mostrarle cómo puede traducir un objeto para dictarlo
dict(obj)
.La sección clave de este código es la
__iter__
función.Como explican los comentarios, lo primero que hacemos es tomar los elementos de la Clase y evitar cualquier cosa que comience con '__'.
Una vez que haya creado eso
dict
, puede usar laupdate
función dict y pasar la instancia__dict__
.Estos le darán un diccionario completo de clase + instancia de miembros. Ahora todo lo que queda es iterar sobre ellos y obtener los rendimientos.
Además, si planea usar esto mucho, puede crear un
@iterable
decorador de clase.fuente
dict((x, y) for x, y in KpiRow.__dict__.items() if x[:2] != '__' and not callable(y))
lo resuelva? Pero todavía podría haberstatic
métodos :(Esto pierde atributos que el objeto hereda de su clase. Por ejemplo,
hasattr (a, 'x') es verdadero, pero 'x' no aparece en un .__ dict__
fuente
vars()
que no funcionadir
es la solución en este caso. Vea la otra respuesta sobre eso.Respuesta tardía pero siempre completa y en beneficio de los googlers:
Esto no mostrará los métodos definidos en la clase, pero aún mostrará campos que incluyen los asignados a lambdas o aquellos que comienzan con un doble guión bajo.
fuente
Creo que la forma más fácil es crear un atributo getitem para la clase. Si necesita escribir en el objeto, puede crear una costumbre setattr . Aquí hay un ejemplo para getitem :
dict genera los atributos de los objetos en un diccionario y el objeto del diccionario se puede usar para obtener el elemento que necesita.
fuente
Una desventaja de usar
__dict__
es que es poco profunda; no convertirá ninguna subclase a diccionarios.Si está utilizando Python3.5 o superior, puede usar
jsons
:fuente
Si desea enumerar parte de sus atributos, anule
__dict__
:Esto ayuda mucho si
instance
obtiene algunos datos de bloque grandes y desea enviard
a Redis como cola de mensajes.fuente
__dict__
es un atributo, no un método, por lo que este ejemplo cambia la interfaz (es decir, debe llamarlo como invocable), por lo que no lo anula.PITÓN 3:
Ahora puede usar el código anterior dentro de su propia clase:
fuente
vars()
es genial, pero no funciona para objetos anidados de objetosConvierte objetos anidados de objetos a dict:
fuente