การส่งออก / นำเข้าต้นไม้ที่สร้างด้วยไลบรารี python anytree 2.4.3

ฉันสร้างต้นไม้ด้วยห้องสมุด 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 แล้วนำเข้ากลับ โหนดเดียวที่ฉันดูเหมือนจะสามารถอ้างอิงได้คือรูท ดังนั้นฉันจึงไม่สามารถแก้ไขประเภทนี้ได้อีกต่อไปเนื่องจากไม่มีชื่อตัวแปรเช่น dan หรือ marc นั่นก็คือ ฉันไม่พบวิธีอ้างอิงโหนด ฉันขาดอะไรไปหรือเปล่า?

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 ที่เหมาะสม ซึ่งคุณสามารถต่อท้ายโหนดใหม่ได้หรือไม่


person gaurwraith    schedule 17.08.2018    source แหล่งที่มา
comment
คุณสามารถอ้างอิงถึงราก, ลูกของมัน, ลูกของมัน, ฯลฯ   -  person Stop harming Monica    schedule 18.08.2018
comment
@Goyo ฉันได้เพิ่มคำถามบางอย่างที่เกิดขึ้นหลังจากแนวคิดนี้ (คิดแต่ไม่รู้จะไปยังไง พูดเป็นโหนดระดับ 5 ดูซับซ้อนมาก ไม่รู้จริง ๆ หรือเปล่าว่าใช่   -  person gaurwraith    schedule 18.08.2018
comment
แต่ฉันจะทำสิ่งนี้ได้อย่างไรโดยไม่ต้องเข้ารหัสยาก ?? คุณหมายความว่าอย่างไร? ในการผูกตัวแปร คุณต้องกำหนดค่า variable = value ซึ่งไม่มีวิธีอื่น ดูเหมือนว่าบางอันไม่ทำงานเนื่องจากโหนด .children ส่งคืนทูเพิล ไม่ใช่โหนด และดูเหมือนว่าฉันก็ไม่รู้จะเพิ่มลูกอย่างไร แล้ว sonny = Node("Sonny", parent = dan) ล่ะ?   -  person Stop harming Monica    schedule 18.08.2018
comment
@Goyo รหัสบรรทัดสุดท้ายที่ฉันเคยลองมาก่อนใช้งานไม่ได้เพราะหลังจากส่งออกคุณจะได้รับสิ่งอันดับเท่านั้นไม่ใช่โหนด ต้นไม้ต้นนี้มี 6 โหนด แต่ฉันคิดว่าจะมี 600 โหนด สองระดับแรกได้รับการแก้ไขแล้วจึงเพิ่มเมื่อฉันพบโหนดใหม่ จะต้องมีวิธีที่แตกต่างจากแต่ละโหนดที่สร้างอินสแตนซ์ด้วย node = Node (ชื่อ, parent = parent) นั่นคือสิ่งที่ฉันหมายถึงด้วยการเขียนโค้ดแบบฮาร์ด ความคิดของฉันคือเมื่อฉันพบบางสิ่งที่อยู่ในสาขา ฉันสามารถใช้ฟังก์ชันที่ระบุว่าผนวก newnode นี้ภายใต้ nodeX ได้ จากนั้นบันทึกและครั้งต่อไปที่ฉันโหลดแผนผังโหนดใหม่ก็จะอยู่ที่นั่น   -  person gaurwraith    schedule 18.08.2018
comment
.children ส่งคืน tuple ของโหนดเสมอ การส่งออกไม่เกี่ยวอะไรกับโหนดนั้น หากต้องการต่อท้าย newnode ใต้ nodeX สมมติว่าทั้ง newnode และ nodeX เป็นโหนด คุณเพียงแค่ทำ newnode.parent = nodeX   -  person Stop harming Monica    schedule 18.08.2018
comment
@gaurwraith ลองดูด้านล่าง จริงๆ แล้ว anytree มีพฤติกรรมเหมือนที่คุณคาดหวังไว้ว่าคุณลืม ,   -  person Fabian N.    schedule 18.08.2018


คำตอบ (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"))
person Fabian N.    schedule 18.08.2018
comment
ใช่แล้ว จริงๆ แล้ว สาเหตุของปัญหาก็คือ แม้แต่โหนดเดียวก็ยังได้รับในรูปแบบทูเพิล! - person gaurwraith; 18.08.2018