1. 问题背景
我们有一个静态的多层级表单,需要使用 Python 对其进行建模,以便于我们能够在代码中对表单中的特定层级或子树进行获取和操作。例如,我们希望能够做到以下操作:
代码语言:javascript复制>>> MyForm.getQuestionObjects()
[Question1, Question1.1, Question2.1, Question2.1.1, Question2.1.2, Question2]
>>> MyForm.Part2.getQuestionObjects()
[Question2.1, Question2.1.1, Question2.1.2]
>>> # Get questions (return class members)
>>> MyForm.SubPart1.getQuestions()
(('2.1.1 text', otherAttributes), ('2.1.2 text', otherAttributes))
>>> # Get questions -- but replace an attribute on 2.1.2
>>> MyForm.Part2.getQuestions(replace_attr('Question_2_1_2', 'text', 'New text'))
(('2.1.1 text', otherAttributes), ('New text', otherAttributes))
2. 解决方案
2.1 使用 XML 作为数据存储
我们可以将这种层级结构的数据存储在 XML 文件中,并使用 xml.etree.ElementTree
标准模块将 XML 文件加载到 Python 中的层级数据结构。这样,我们就可以对 XML 数据进行操作,并在需要时将其保存回文件。
例如,我们可以使用以下代码来加载 XML 文件并获取表单中的所有问题:
代码语言:javascript复制import xml.etree.ElementTree as ET
# 加载 XML 文件
tree = ET.parse('form.xml')
# 获取表单根节点
form_root = tree.getroot()
# 获取表单中的所有问题
questions = []
for question in form_root.iter('question'):
questions.append(question)
# 打印问题列表
print(questions)
2.2 使用嵌套类创建数据结构
我们可以使用 Python 中的嵌套类来创建层次化的数据结构。嵌套类可以让我们定义一个类,该类的实例可以作为另一个类的成员。
例如,我们可以使用以下代码来定义一个 Form
类,该类具有 Part
和 Question
子类:
class Form:
def __init__(self, title):
self.title = title
self.parts = []
def add_part(self, part):
self.parts.append(part)
def get_question_objects(self):
question_objects = []
for part in self.parts:
question_objects.extend(part.get_question_objects())
return question_objects
class Part:
def __init__(self, title):
self.title = title
self.questions = []
def add_question(self, question):
self.questions.append(question)
def get_question_objects(self):
question_objects = []
for question in self.questions:
question_objects.append(question)
return question_objects
class Question:
def __init__(self, title, details, answers):
self.title = title
self.details = details
self.answers = answers
然后,我们可以使用这些类来创建我们的表单数据结构:
代码语言:javascript复制form = Form('My Form')
part1 = Part('Part 1')
part1.add_question(Question('Question 1.1', 'Details for Question 1.1', ['Answer 1.1.1', 'Answer 1.1.2']))
part2 = Part('Part 2')
part2.add_question(Question('Question 2.1', 'Details for Question 2.1', ['Answer 2.1.1', 'Answer 2.1.2']))
part2.add_question(Question('Question 2.2', 'Details for Question 2.2', ['Answer 2.2.1', 'Answer 2.2.2']))
form.add_part(part1)
form.add_part(part2)
# 获取表单中的所有问题
question_objects = form.get_question_objects()
# 打印问题列表
print(question_objects)