嵌套对象操纵
nob的Python项目详细描述
nob:嵌套对象操纵器
json是嵌套数据交换和对象关系的一种非常流行的格式 映射(orm)是帮助开发人员理解大型json的一种流行方法 对象,通过将对象映射到数据。然而,在某些情况下,嵌套 可能很深,而且很难与对象映射。这是诺布可以去的地方 有用:它提供了一组简单的工具来浏览和编辑任何嵌套的数据 (python本地指令和列表)。
有关更多信息,请查看主页
用法
实例化
nob.tree
对象可以直接从python字典实例化:
t = Tree({
'key1': 'val1',
'key2': {
'key3': 4,
'key4': {'key5': 'val2'},
'key5': [3, 4, 5]
},
'key5': 'val3'
})
要从json(或yaml)文件创建树
致构造器:
import json
with open('file.json') as fh:
t2 = Tree(json.load(fh))
import yaml
with open('file.yml') as fh:
t3 = Tree(yaml.load(fh))
类似地,要从树创建json(yaml)文件,可以使用:
with open('file.json', 'w') as fh:
json.dump(t2.val, fh)
with open('file.yml', 'w') as fh:
yaml.dump(t3.val, fh)
基本操作
变量t
现在保存一个树,即对实际数据的引用。然而,
对于许多实际情况,使用子树是很有用的。nob
提供了一个有用的
为此,classtreeview
。它处理的大部分和主树一样,
但是在treeview
上执行的更改会影响链接的主tree
实例
去。实际上,任何对t
键的访问都会生成一个treeview
实例,例如::
tv1 = t['/key1'] # TreeView(/key1)
tv2 = t['key1'] # TreeView(/key1)
tv3 = t.key1 # TreeView(/key1)
tv1 == tv2 == tv3 # True
请注意,完整路径和简单键都是有效的
标识符。简单键也可以称为属性,使用t.key1
要访问嵌套对象中存储的实际值,只需使用.val
方法:< > >
tv1.val >>> 'val1'
t.key1.val >>> 'val1'
要为此节点分配新值,可以直接在treeview实例上执行此操作:
t.key1 = 'new'
tv1.val >>> 'new'
t.val['key1'] >>> 'new'
当然,由于python变量的工作方式,您不能简单地将值赋给
tv1
,因为这会覆盖它的内容:
tv1 = 'new'
tv1 >>> 'new'
t.val['key1'] >>> 'val1'
如果您发现自己有一个要直接编辑的treeview
对象,
您可以使用。set
方法:
tv1 = t.key1
tv1.set('new')
t.val['key1'] >>> 'new'
因为嵌套对象可以同时包含dict和list,所以整数有时是 需要用作键:
t['/key2/key5/0'] >>> TreeView(/key2/key5/0)
t.key2.key5[0] >>> TreeView(/key2/key5/0)
t.key2.key5['0'] >>> TreeView(/key2/key5/0)
但是,由于python不支持以整数开头的属性,因此 列表没有属性支持。仅密钥访问(完整路径、整数索引或其 支持字符串化的对应项。
智能钥匙接入
在一个简单的嵌套字典中,对'key1'
的访问只需使用:
t = Tree({
'key1': 'val1',
'key2': {
'key3': 4,
'key4': {'key5': 'val2'},
'key5': [3, 4, 5]
},
'key5': 'val3'
})
0
如果您要查找例如key3
,则需要编写:
t = Tree({
'key1': 'val1',
'key2': {
'key3': 4,
'key4': {'key5': 'val2'},
'key5': [3, 4, 5]
},
'key5': 'val3'
})
1
但是,对于深嵌套对象,这可能是一项繁重的工作,并且很难
读。nob
为您提供了一种智能的方法来查找唯一的密钥:
t = Tree({
'key1': 'val1',
'key2': {
'key3': 4,
'key4': {'key5': 'val2'},
'key5': [3, 4, 5]
},
'key5': 'val3'
})
2
注意,属性访问t.key3
的行为类似于简单的键访问t['key3']
。这个
当密钥在树中不唯一时会有一些影响。假设我们希望
访问键5。让我们尝试使用属性访问:
t = Tree({
'key1': 'val1',
'key2': {
'key3': 4,
'key4': {'key5': 'val2'},
'key5': [3, 4, 5]
},
'key5': 'val3'
})
3
哎哟!因为key5
不是唯一的(它在树中出现了3次),t.key5
不是唯一的
具体的,nob
不知道返回哪一个。在这种情况下,我们有
有几种可能性,具体取决于我们正在寻找的键5
t = Tree({
'key1': 'val1',
'key2': {
'key3': 4,
'key4': {'key5': 'val2'},
'key5': [3, 4, 5]
},
'key5': 'val3'
})
4
这里有一点需要解包:
- 第一个
key5
在treeview
t.key4
中是唯一的(并且key4
本身就是 唯一),因此t.key4.key5正确找到它。 - 第二个是复杂的:
key2
是唯一的,但是key5
对于t.key2
仍然不是唯一的。 与全路径访问相比,没有太多优势t['/key2/key5']
- 最后一罐不能使用其路径中的键来解析,因为没有键。这个 唯一的解决方案是使用完整路径。
其他树工具
路径:任何树
(或树视图
)对象都可以自省以找到其所有有效路径:
t = Tree({
'key1': 'val1',
'key2': {
'key3': 4,
'key4': {'key5': 'val2'},
'key5': [3, 4, 5]
},
'key5': 'val3'
})
5
查找:为了方便在此路径列表中搜索,可以使用.find
方法:
t = Tree({
'key1': 'val1',
'key2': {
'key3': 4,
'key4': {'key5': 'val2'},
'key5': [3, 4, 5]
},
'key5': 'val3'
})
6
如前所述,这些列表的元素不是字符串,而是path
对象
下面,
iterable:任何树或树视图也都是iterable,生成其子级:
t = Tree({
'key1': 'val1',
'key2': {
'key3': 4,
'key4': {'key5': 'val2'},
'key5': [3, 4, 5]
},
'key5': 'val3'
})
7
复制:要制作树的独立副本,请使用其.copy()
方法:
t = Tree({
'key1': 'val1',
'key2': {
'key3': 4,
'key4': {'key5': 'val2'},
'key5': [3, 4, 5]
},
'key5': 'val3'
})
8
也可以从任何树视图生成新的独立树:
t = Tree({
'key1': 'val1',
'key2': {
'key3': 4,
'key4': {'key5': 'val2'},
'key5': [3, 4, 5]
},
'key5': 'val3'
})
9
路径
所有路径都使用nob.path
类在内部存储。路径已满
(w.r.t.它们的树
或树视图
),本质上是一个键列表
构成嵌套地址。然而,它们可以被等同地视为
带有分隔符的unix类型路径字符串。下面是一些示例
import json
with open('file.json') as fh:
t2 = Tree(json.load(fh))
import yaml
with open('file.yml') as fh:
t3 = Tree(yaml.load(fh))
0
这些可以帮助您自己操纵路径,就像使用
指向树
或树视图
对象的字符串也接受路径
对象。所以说
您可以在一个位置访问list_of_keys
中的键,但也可以
存在于树的其他地方。您可以使用例如::
import json
with open('file.json') as fh:
t2 = Tree(json.load(fh))
import yaml
with open('file.yml') as fh:
t3 = Tree(yaml.load(fh))
1