从对象字段创建Python字典
你知道有没有内置的函数可以从一个任意对象创建字典吗?我想做类似这样的事情:
>>> class Foo:
... bar = 'hello'
... baz = 'world'
...
>>> f = Foo()
>>> props(f)
{ 'bar' : 'hello', 'baz' : 'world' }
注意:它只应该包含字段,不包括方法。
21 个回答
73
dir
这个内置函数可以让你看到一个对象的所有属性,包括一些特殊的方法,比如__str__
、__dict__
,还有很多你可能不需要的其他方法。不过,你可以这样做:
>>> 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' }
你可以通过定义你的props
函数来让它只返回数据属性,而不包括方法,像这样:
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
248
与其使用 x.__dict__
,不如用 vars(x)
这种写法更符合 Python 的风格。
613
请注意,在Python 2.7中,最佳实践是使用新式类(在Python 3中不需要这样做),也就是说:
class Foo(object):
...
另外,'对象'和'类'是有区别的。要从一个任意的对象构建一个字典,只需要使用__dict__
就可以了。通常,你会在类中声明方法,而在实例中声明属性,所以使用__dict__
是没问题的。例如:
>>> 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}
一种更好的方法(由robert在评论中建议)是使用内置的vars
函数:
>>> vars(a)
{'c': 2, 'b': 1}
另外,根据你想做的事情,继承dict
也是个不错的选择。这样你的类就已经是一个字典了,如果需要的话,你可以重写getattr
和/或setattr
来调用和设置字典。例如:
class Foo(dict):
def __init__(self):
pass
def __getattr__(self, attr):
return self[attr]
# etc...