Mengekspor / Mengimpor pohon yang dibuat dengan pustaka python anytree 2.4.3

Saya membuat pohon dengan perpustakaan pohon apa pun. Saya ingin dapat memodifikasinya, lalu mengekspor - menyimpannya ke disk, dan mengimpornya kembali dengan modifikasinya. Misalnya, contoh pohon:

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

Saya bisa memodifikasinya, misalnya memotong Dan dan menambahkan anak ke Marc

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

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

Tetapi ketika saya mengekspor pohon ke json dan kemudian mengimpornya kembali, satu-satunya node yang dapat saya referensikan adalah root. Jadi saya tidak bisa melakukan modifikasi seperti ini lagi karena nama variabel seperti dan atau marc tidak ada, yaitu saya tidak menemukan cara untuk mereferensikan sebuah node. Apakah saya melewatkan sesuatu?

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

print (datos)

Artinya setelah mengimpor pohon yang Anda miliki hanyalah simpul akar

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

Dari sini Anda bisa mendapatkan anak-anak Udo, dan anak-anak suka

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

Tapi mereka tidak bekerja sebagai sebuah node

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

Dan sepertinya Anda tidak dapat melampirkan anak-anak ke dalamnya, itulah tujuan utama saya dengan struktur ini:

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

Jadi pertanyaan saya adalah, apakah ada cara untuk memuat pohon json yang disimpan ke dalam struktur pohon apa pun yang tepat, tempat Anda dapat menambahkan node baru?


person gaurwraith    schedule 17.08.2018    source sumber
comment
Anda dapat mereferensikan root, anak-anaknya, anak-anaknya, dll.   -  person Stop harming Monica    schedule 18.08.2018
comment
@Goyo Saya menambahkan beberapa pertanyaan yang muncul setelah ide ini. (Saya merenungkannya, tetapi tidak tahu bagaimana saya akan pergi ke, katakanlah, node level 5, terlihat sangat rumit, saya benar-benar tidak tahu apakah itu benar.   -  person gaurwraith    schedule 18.08.2018
comment
Tetapi bagaimana saya melakukan ini tanpa mengkodekannya dengan keras ?? Apa maksudmu? Untuk mengikat variabel, Anda perlu menetapkan nilai variable = value, tidak ada cara lain. Juga sepertinya ada yang tidak berfungsi karena node .children mengembalikan tuple, bukan node. Dan sepertinya saya juga tidak tahu cara menambah anak. Bagaimana kalau sonny = Node("Sonny", parent = dan)?   -  person Stop harming Monica    schedule 18.08.2018
comment
@Goyo baris kode terakhir itu, saya sudah mencobanya sebelumnya, tidak berhasil, justru karena setelah mengekspor Anda hanya mendapatkan tupel bukan node. Pohon ini juga memiliki 6 node tetapi saya pikir saya akan memiliki 600, dua level pertama diperbaiki kemudian ditambahkan saat saya menemukan node baru. Pasti ada cara yang berbeda untuk setiap node yang membuat instance-nya dengan node = Node (Nama, induk = induk) Itulah yang saya maksud dengan hard coding. Ide saya adalah ketika saya menemukan sesuatu yang termasuk dalam cabang, saya cukup menggunakan fungsi yang mengatakan append this newnode under nodeX . Kemudian simpan dan lain kali saya memuat pohon, simpul baru sudah ada di sana   -  person gaurwraith    schedule 18.08.2018
comment
.children selalu mengembalikan sejumlah node, mengekspor tidak ada hubungannya dengan itu. Untuk menambahkan newnode di bawah nodeX, dengan asumsi newnode dan nodeX adalah node, cukup lakukan newnode.parent = nodeX.   -  person Stop harming Monica    schedule 18.08.2018
comment
@gaurwraith lihat di bawah, pohon apa pun sebenarnya berperilaku seperti yang Anda harapkan, Anda baru saja lupa ,   -  person Fabian N.    schedule 18.08.2018


Jawaban (1)


Anda sebenarnya melakukannya dengan cara yang benar: Anda baru saja lupa ,

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')

@Cara menemukan node Anda: Anda mencari pohon apa saja find_by_attr:

Cari satu node dengan nama atribut yang memiliki nilai [...]

Jadi setelah memuat pohon Anda dengan

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

Anda dapat mencari node berdasarkan nama:

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

Dan kemudian tambahkan lebih banyak seperti ini:

Node("Sonny", parent = datos.find_by_attr("lian"))
person Fabian N.    schedule 18.08.2018
comment
Ya, memang, akar masalahnya adalah, bahkan node tunggal pun diberikan dalam bentuk tuple! - person gaurwraith; 18.08.2018