1

使用任意字典(最终具有嵌套集合和基本类型),使用 python-attrs 使其成为嵌套对象列表的最佳方法是什么?

一些限制:字典键始终是字符串(即有效的 Python 标识符),其值仅包含本机集合类型、字符串、整数和浮点数。任何完全深度的嵌套字典都将始终具有相同的特征。在任何列表或元组中,所有项目都将是相同类型或无。而且很可能我的字典将始终是有序映射,因此该顺序应保留在生成的顶级列表和每个嵌套映射中。

例如:

{'some_key': [
  {'some_value': 12, 'foo': 'abc', 'bar': [1, 4, 8], 'baz': None}
  {'some_value': 24, 'foo': 'xyz', 'bar': [12, 12], 'baz': 'this'}],
 'other_key' : [1,2,3,4]
}

我想得到一个可以使用属性遍历的两个对象的列表:

some_key[0].some_value, some_key[0].baz 
other_key[-1]

即,结果将是“对象化”嵌套映射。我怎么能用 attrs 做到这一点?是一些循环attr.make_class()调用的方式吗?

4

3 回答 3

0

所以最终我想出了一个稍微不同的客观化解决方案(并且可以很容易地为此扩展):

这是使用attr.make_class. 在我的情况下,“pluggy”插件类(pluggy 是使用的插件库和 from )正在为数据对象py.test贡献新的数据属性。然后我调用构建我的数据类的新子类,向该子类添加新属性。我本可以避免声明这些属性,而是通过对贡献属性的数据类型的递归自省来动态构建它们……但我选择了显式而不是隐式;)make_classattr.ib

在此过程中,在类主体之外创建的方式存在一个小错误attr.ib可能无法使用我期望的顺序附加到新的子类,@hynek 以超快的速度解决了这个问题

于 2018-02-07T06:43:05.173 回答
0

我不知道您为什么要为此使用 attrs 的原因,因为为此目的有特定的库:Box

from box import Box

a_dict = {'some_key': [
    {'some_value': 12, 'foo': 'abc', 'bar': [1, 4, 8], 'baz': None},
    {'some_value': 24, 'foo': 'xyz', 'bar': [12, 12], 'baz': 'this'}],
    'other_key': [1, 2, 3, 4]
}

box_dict = Box(a_dict)

assert box_dict.some_key[0].some_value == 12
assert box_dict.some_key[0].baz == None
assert box_dict.other_key[-1] == 4
于 2020-11-20T16:34:26.240 回答
-1

说明为什么要拥有对象而不是简单地使用字典可能会有所帮助。您的示例用法是:

some_key[0].some_value, some_key[0].baz 
other_key[-1]

不同之处在于:

some_key[0]["some_value"], some_key[0]["baz"]
other_key[-1]

您在这里寻找的唯一东西是获取点访问语法吗?

attrsattrs旨在为您提供一种更简单地定义类的方法,而不是将非结构化数据包装到未预定义类型的对象中的方法,因此这不像attrs是要解决的用例。

于 2018-02-08T20:36:17.303 回答