【问题标题】:Exporting / Importing trees created with python anytree 2.4.3 library导出/导入使用 python anytree 2.4.3 库创建的树
【发布时间】:2018-08-17 22:53:17
【问题描述】:

我用 anytree 库创建了一棵树。我希望能够对其进行修改,然后导出 - 将其保存到磁盘,然后将其与修改一起导入回来。例如示例树:

udo = Node("Udo")
marc = Node("Marc", parent=udo)
lian = Node("Lian", parent=marc)
dan = Node("Dan", parent=udo)
jet = Node("Jet", parent=dan)
jan = Node("Jan", parent=dan)
joe = Node("Joe", parent=dan)

Udo
├── Marc
│   └── Lian
└── Dan
    ├── Jet
    ├── Jan
    └── Joe

我可以修改它,例如切断 Dan 并为 Marc 添加一个孩子

dan.parent = None 
bonny = Node ("Bonny", parent = marc)

Udo
└── Marc
    ├── Lian
    └── Bonny

但是当我将树导出为 json 然后将其导入回来时,我似乎能够引用的唯一节点是根。所以我不能再做这种修改,因为像danmarc这样的变量名不存在,即我找不到引用节点的方法。我错过了什么吗?

with open ('cajon/anytreeexample.json', 'r+', encoding = 'utf-8') as f:
    datos = importer.read(f)

print (datos)

这意味着在导入树之后你所拥有的只是一个根节点

AnyNode(name='Udo')  # Udo is the root

从这里你可以得到Udo的孩子,孩子的孩子喜欢

marc, dan = udo.children
lian = marc.children
jet, jan, joe = dan.children

但它们不能作为节点工作

print (lian.parent)
AttributeError: 'tuple' object has no attribute 'parent'

而且您似乎不能将孩子附加到他们身上,这是我使用此结构的主要目的:

sonny = AnyNode("Sonny", parent = lian)
TypeError: __init__() got multiple values for argument 'parent'

所以我的问题是,有没有办法将 json 保存的树加载到适当的 anytree 结构中,您可以在其中添加新节点?

【问题讨论】:

  • 你可以引用根、它的孩子、它的孩子的孩子等等。
  • @Goyo 我添加了一些在这个想法之后出现的问题。 (想过,但是不知道怎么去,比如说5级节点,看起来很复杂,真不知道是不是
  • "但是如果不进行硬编码,我该怎么做呢??"你什么意思?为了绑定一个变量你需要赋值variable = value,没有别的办法。 “而且似乎有些人不能作为节点工作”.children 返回一个元组,而不是一个节点。 “而且我似乎也不知道如何添加孩子”sonny = Node("Sonny", parent = dan) 怎么样?
  • @Goyo 最后一行代码,我之前尝试过,但不起作用,正是因为导出后你只得到元组而不是节点。这棵树也有 6 个节点,但我想我会有 600 个,前两个级别固定,然后在找到新节点时添加。必须有一种不同于使用 node = Node ("Name", parent = parent) 实例化它的每个节点的方式,这就是我对硬编码的意思。我的想法是,当我找到属于某个分支的东西时,我可以使用一个函数,上面写着“将这个新节点附加到 nodeX 下”。然后保存它,下次我加载树时,新节点就在那里
  • .children 总是返回一个节点元组,与导出无关。为了在nodeX 下附加newnode,假设newnodenodeX 都是节点,您只需执行newnode.parent = nodeX

标签: python tree python-3.6 anytree


【解决方案1】:

实际上你做对了:你只是忘记了,

from anytree import Node

udo = Node("Udo")
marc = Node("Marc", parent=udo)
Node("Lian", parent=marc)

lian, = marc.children # this is a tupel, even if its only one entry -> add ,
sonny = Node("Sonny", parent = lian)

print (lian.parent)
> Node('/Udo/Marc')

print (sonny)
> Node('/Udo/Marc/Lian/Sonny')

@如何找到你的节点:你正在寻找anytrees find_by_attr

搜索具有值 [...] 的属性名称的单个节点

所以在加载你的树之后

with open ('cajon/anytreeexample.json', 'r+', encoding = 'utf-8') as f:
    datos = importer.read(f)

您可以按名称搜索节点:

udo = datos.find_by_attr("Udo") # should be the same as datos if udo was the root

然后像这样添加更多:

Node("Sonny", parent = datos.find_by_attr("lian"))

【讨论】:

  • 是的,确实,问题的根源在于,即使是单个节点也以元组形式给出!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-15
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
相关资源
最近更新 更多