【问题标题】:how do I create a dict with all fields and properties of a python object?如何创建一个包含 python 对象的所有字段和属性的字典?
【发布时间】:2018-01-25 20:04:54
【问题描述】:

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

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__vars,但@property 仍然没有出现。我怎样才能包括@property

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

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

【问题讨论】:

  • 您可以访问 TestClass.__dict__ 上的属性。所以我想你可以遍历这些并添加名称如果type == property

标签: python class object properties


【解决方案1】:

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

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

【讨论】:

  • OP 在哪里声明他不想要继承的属性?
  • @RichardNeumann 问题的最后一行说“我想将age_groupcountry 包含在返回的值中作为键和值。”换句话说,除了他的代码当前正在打印的实例属性之外,他只想要那些 property 键值对。你的代码还打印了一堆方法,我不认为他想要这些。
【解决方案2】:

使用迭代对象属性的字典推导:

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}

【讨论】:

    猜你喜欢
    • 2011-07-13
    • 2012-03-09
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 2019-03-17
    相关资源
    最近更新 更多