本文翻译自:Python dictionary from an object's fields
Do you know if there is a built-in function to build a dictionary from an arbitrary object? 你知道是否有一个内置函数来从任意对象构建一个字典? I'd like to do something like this: 我想做这样的事情:
>>> class Foo:
... bar = 'hello'
... baz = 'world'
...
>>> f = Foo()
>>> props(f)
{ 'bar' : 'hello', 'baz' : 'world' }
NOTE: It should not include methods. 注意:它不应包括方法。 Only fields. 只有字段。
#1楼
参考:https://stackoom.com/question/G0D/来自对象字段的Python字典
#2楼
Late answer but provided for completeness and the benefit of googlers: 迟到的答案,但提供了完整性和googlers的好处:
def props(x):
return dict((key, getattr(x, key)) for key in dir(x) if key not in dir(x.__class__))
This will not show methods defined in the class, but it will still show fields including those assigned to lambdas or those which start with a double underscore. 这不会显示在类中定义的方法,但它仍将显示包括分配给lambdas的字段或以双下划线开头的字段。
#3楼
I think the easiest way is to create a getitem attribute for the class. 我认为最简单的方法是为类创建一个getitem属性。 If you need to write to the object, you can create a custom setattr . 如果需要写入对象,则可以创建自定义setattr 。 Here is an example for getitem : 以下是getitem的示例:
class A(object):
def __init__(self):
self.b = 1
self.c = 2
def __getitem__(self, item):
return self.__dict__[item]
# Usage:
a = A()
a.__getitem__('b') # Outputs 1
a.__dict__ # Outputs {'c': 2, 'b': 1}
vars(a) # Outputs {'c': 2, 'b': 1}
dict generates the objects attributes into a dictionary and the dictionary object can be used to get the item you need. dict将对象属性生成到字典中,字典对象可用于获取所需的项目。
#4楼
I thought I'd take some time to show you how you can translate an object to dict via dict(obj)
. 我想我会花一些时间向你展示你如何通过dict(obj)
将一个对象翻译成dict。
class A(object):
d = '4'
e = '5'
f = '6'
def __init__(self):
self.a = '1'
self.b = '2'
self.c = '3'
def __iter__(self):
# first start by grabbing the Class items
iters = dict((x,y) for x,y in A.__dict__.items() if x[:2] != '__')
# then update the class items with the instance items
iters.update(self.__dict__)
# now 'yield' through the items
for x,y in iters.items():
yield x,y
a = A()
print(dict(a))
# prints "{'a': '1', 'c': '3', 'b': '2', 'e': '5', 'd': '4', 'f': '6'}"
The key section of this code is the __iter__
function. 该代码的关键部分是__iter__
函数。
As the comments explain, the first thing we do is grab the Class items and prevent anything that starts with '__'. 正如评论所解释的那样,我们要做的第一件事就是抓住Class项并防止任何以'__'开头的内容。
Once you've created that dict
, then you can use the update
dict function and pass in the instance __dict__
. 一旦你创建了那个dict
,那么你可以使用update
dict函数并传入实例__dict__
。
These will give you a complete class+instance dictionary of members. 这些将为您提供完整的成员类+实例字典。 Now all that's left is to iterate over them and yield the returns. 现在剩下的就是迭代它们并产生回报。
Also, if you plan on using this a lot, you can create an @iterable
class decorator. 此外,如果您打算大量使用它,您可以创建一个@iterable
类装饰器。
def iterable(cls):
def iterfn(self):
iters = dict((x,y) for x,y in cls.__dict__.items() if x[:2] != '__')
iters.update(self.__dict__)
for x,y in iters.items():
yield x,y
cls.__iter__ = iterfn
return cls
@iterable
class B(object):
d = 'd'
e = 'e'
f = 'f'
def __init__(self):
self.a = 'a'
self.b = 'b'
self.c = 'c'
b = B()
print(dict(b))
#5楼
而不是x.__dict__
,使用vars(x)
实际上更加pythonic。
#6楼
If you want to list part of your attributes, override __dict__
: 如果要列出部分属性,请覆盖__dict__
:
def __dict__(self):
d = {
'attr_1' : self.attr_1,
...
}
return d
# Call __dict__
d = instance.__dict__()
This helps a lot if your instance
get some large block data and you want to push d
to Redis like message queue. 如果您的instance
获得一些大块数据并且您希望将d
推送到Redis(如消息队列),这会有很大帮助。