如何创建包含python对象的所有字段和属性的dict?

时间:2017-08-17 12:00:08

标签: python class object properties

假设我有一个如下所示的课程,

class TestClass(object):

    def __init__(self):
        self.name = 'Marty'
        self.age = 25
        self.place = 'CL'

    @property
    def country(self):
        return 'USA'

    @property
    def age_group(self):
        return '18-25'

我想从所有@properties中创建一个dict。我尝试使用__dict__vars,但@property仍未显示。我怎样才能包含@property

>>> x = TestClass()
>>> x.__dict__
{'age': 25, 'name': 'Marty', 'place': 'CL'}
>>> vars(x)
{'age': 25, 'name': 'Marty', 'place': 'CL'}

我希望将age_groupcountry包含在返回值中作为键和值。

2 个答案:

答案 0 :(得分:3)

使用迭代对象属性的字典理解:

obj = TestClass()
object_dict = {attr: getattr(obj, attr) for attr in dir(obj)}

如果你真的只想要问题中不清楚的@property属性,你可以像这样过滤它们:

object_properties_dict = {attr: getattr(obj, attr) for attr in dir(obj.__class__) if type(getattr(obj.__class__, attr)) is property}

答案 1 :(得分:3)

您可以在实例上调用dir来获取所需的名称。但是,dir返回的列表也有一堆你想要的名称(继承自object的方法的名称),所以我们需要过滤那些进行。

class TestClass(object):
    def __init__(self):
        self.name = 'Marty'
        self.age = 25
        self.place = 'CL'

    @property
    def country(self):
        return 'USA'

    @property
    def age_group(self):
        return '18-25'

x = TestClass()
d = {k: getattr(x, k) for k in dir(x) if not k.startswith('__')}
print(d)

<强>输出

{'age': 25, 'age_group': '18-25', 'country': 'USA', 'name': 'Marty', 'place': 'CL'}

这是一种更清洁的方法。我们循环遍历类对象的vars(),特别是查找property个实例的项目。然后我们使用itertools.chain将这些名称与在类的实例上调用vars()的名称组合。

from itertools import chain

class TestClass(object):
    def __init__(self):
        self.name = 'Marty'
        self.age = 25
        self.place = 'CL'

    @property
    def country(self):
        return 'USA'

    @property
    def age_group(self):
        return '18-25'

    def do_stuff(self):
        return 'hello'

def attributes_and_properties(obj):
    props = (k for k, ktype in vars(type(obj)).items() 
        if isinstance(ktype, property))
    return {k: getattr(obj, k) for k in chain(props, vars(obj))}

x = TestClass()
print(attributes_and_properties(x))

<强>输出

{'country': 'USA', 'age_group': '18-25', 'name': 'Marty', 'age': 25, 'place': 'CL'}

这种方式优于以前的技术,因为该代码还将在其输出中包含名称不以__开头的绑定方法,如do_stuff