Diccionario Python de los campos de un objeto.
¿Sabe si existe una función incorporada para crear un diccionario a partir de un objeto arbitrario? Me gustaría hacer algo como esto:
>>> class Foo:
... bar = 'hello'
... baz = 'world'
...
>>> f = Foo()
>>> props(f)
{ 'bar' : 'hello', 'baz' : 'world' }
NOTA: No debe incluir métodos. Sólo campos.
Tenga en cuenta que la mejor práctica en Python 2.7 es utilizar clases de nuevo estilo (no necesarias con Python 3), es decir
class Foo(object):
...
Además, existe una diferencia entre un "objeto" y una "clase". Para construir un diccionario a partir de un objeto arbitrario , es suficiente usar __dict__
. Por lo general, declararás tus métodos a nivel de clase y tus 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, podría ser bueno heredar de dict
. Entonces su clase ya es un diccionario y, si lo desea, puede anular getattr
y/o setattr
llamar y configurar el dict. Por ejemplo:
class Foo(dict):
def __init__(self):
pass
def __getattr__(self, attr):
return self[attr]
# etc...
En lugar de x.__dict__
, en realidad es más pitónico de usar vars(x)
.
El dir
incorporado le brindará todos los atributos del objeto, incluidos métodos especiales como __str__
y __dict__
muchos otros que probablemente no desee. Pero puedes hacer algo como:
>>> class Foo(object):
... bar = 'hello'
... baz = 'world'
...
>>> f = Foo()
>>> [name for name in dir(f) if not name.startswith('__')]
[ 'bar', 'baz' ]
>>> dict((name, getattr(f, name)) for name in dir(f) if not name.startswith('__'))
{ 'bar': 'hello', 'baz': 'world' }
Entonces, puedes extender esto para devolver solo atributos de datos y no métodos, definiendo tu props
función de esta manera:
import inspect
def props(obj):
pr = {}
for name in dir(obj):
value = getattr(obj, name)
if not name.startswith('__') and not inspect.ismethod(value):
pr[name] = value
return pr