Python数据结构/对象对静态多维表建模
在中断了几年之后,我才重新开始编写代码,我正试图以一种可以在特定表单级别或整个子树上获取和执行操作的方式对多层静态表单进行建模 表单层次结构示例:Python数据结构/对象对静态多维表建模,python,class,data-structures,data-modeling,inner-classes,Python,Class,Data Structures,Data Modeling,Inner Classes,在中断了几年之后,我才重新开始编写代码,我正试图以一种可以在特定表单级别或整个子树上获取和执行操作的方式对多层静态表单进行建模 表单层次结构示例: MyForm 问题1 第一部分 问题1.1 第二部分 问题2.1 子部分1 问题2.1.1 问题2.1.2 问题2 每个问题都有多个属性(问题文本、是否为必填字段等),并且问题可以位于层次结构的任何级别 我希望能够做到这样: >>> MyForm.getQuestionObjects() [Question1,
- MyForm
- 问题1
- 第一部分
- 问题1.1
- 第二部分
- 问题2.1
- 子部分1
- 问题2.1.1
- 问题2.1.2
- 问题2
>>> 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))
我一直在尝试使用嵌套/内部类来实现这一点,这是一个非常头痛的问题,并且在python中没有得到很好的支持。但是,即使我能找到一个使用嵌套类的解决方案,我仍然想知道是否有更好的方法将表单信息存储在某个地方,使非编码人员更容易编辑(可能是纯文本模板),然后在运行时加载数据,因为它是静态的,我经常需要它在内存中。表单数据每月更新的次数不会超过一次。无论我如何存储数据,我都希望找到一个好的数据结构来表示、遍历和操作数据
- 有没有办法使分层属性对象像这样
- 我可以做一些类似多维命名元组的事情吗
- 还有其他想法吗
谢谢您的评论。我会将这种分层数据以XML格式存储在存储器上。您可以使用
xml.etree.ElementTree
标准模块将这样的xml文件加载到Python中的分层数据结构中,对其进行更改,然后将其保存回文件。这样,您就不必担心实际的数据结构,因为它是由ElementTree自动构建的
请参阅Python手册中的xml.etree.ElementTree。有关更多信息,请参见:
(Python中还有其他成熟的解决方案可以将XML文件加载到各种数据结构中。只需选择一个最容易用于您的任务的解决方案。Google是您的朋友。:-)我会将这种分层数据以XML存储在存储器中。您可以使用
xml.etree.ElementTree
标准模块将这样的xml文件加载到Python中的分层数据结构中,对其进行更改,然后将其保存回文件。这样,您就不必担心实际的数据结构,因为它是由ElementTree自动构建的
请参阅Python手册中的xml.etree.ElementTree。有关更多信息,请参见:
(Python中还有其他成熟的解决方案可以将XML文件加载到各种数据结构中。只需选择一个最容易用于您的任务的解决方案。Google是您的朋友。:-)Python中的嵌套类没有令人头痛或不受支持的地方,只是它们什么都不做。不要期望Java内部类样式的链接自动返回到所有者实例:嵌套类只是普通类,其类对象恰好存储在另一个类的属性中。他们在这里帮不了你 有没有办法使分层属性对象像这样 当然可以,但是您最好扩展Python现有的序列类,以获得所有现有操作的好处。例如,表单“部分”可能只是一个列表,它也有一个标题:
class FormPart(list):
def __init__(self, title, *args):
list.__init__(self, *args)
self.title= title
def __repr__(self):
return 'FormPart(%r, %s)' % (self.title, list.__repr__(self))
现在,您可以说form=FormPart('My form',[question,FormPart…])
并使用普通列表索引和切片访问其中的问题和FormPart
接下来,一个问题可能是一个不变的东西,比如元组,但您可能希望其中的项具有良好的属性名称。因此,将其添加到元组中:
class FormQuestion(tuple):
def __new__(cls, title, details= '', answers= ()):
return tuple.__new__(cls, (title, details, answers))
def __repr__(self):
return 'FormQuestion%s' % tuple.__repr__(self)
title= property(operator.itemgetter(0))
details= property(operator.itemgetter(1))
answers= property(operator.itemgetter(2))
现在,您可以定义数据,如:
form= FormPart('MyForm', [
FormQuestion('Question 1', 'Why?', ('Because', 'Why not?')),
FormPart('Part 1', [
FormQuestion('Question 1.1', details= 'just guess'),
]),
FormPart('Part 2', [
FormQuestion('Question 2.1'),
FormPart('SubPart 1', [
FormQuestion('Question 2.1.1', answers= ('Yes')),
]),
]),
FormQuestion('Question 2'),
])
并访问它:
>>> form[0]
FormQuestion('Question 1', 'Why?', ('Because', 'Why not?'))
>>> form[1].title
'Part 1'
>>> form[2][1]
FormPart('SubPart 1', [FormQuestion('Question 2.1.1', '', 'Yes')])
现在,您可以在FormPart
上定义层次结构:
def getQuestions(self):
for child in self:
for descendant in child.getQuestions():
yield descendant
在表单问题上
:
def getQuestions(self):
yield self
现在您有了一个返回FormQuestions的后代生成器:
>>> list(form[1].getQuestions())
[FormQuestion('Question 1.1', 'just guess', ())]
>>> list(form.getQuestions())
[FormQuestion('Question 1', 'Why?', ('Because', 'Why not?')), FormQuestion('Question 1.1', 'just guess', ()), FormQuestion('Question 2.1', '', ()), FormQuestion('Question 2.1.1', '', 'Yes'), FormQuestion('Question 2', '', ())]
Python中的嵌套类没有令人头痛或不受支持的地方,只是它们什么都不做。不要期望Java内部类样式的链接自动返回到所有者实例:嵌套类只是普通类,其类对象恰好存储在另一个类的属性中。他们在这里帮不了你
有没有办法使分层属性对象像这样
当然可以,但是您最好扩展Python现有的序列类,以获得所有现有操作的好处。例如,表单“部分”可能只是一个列表,它也有一个标题:
class FormPart(list):
def __init__(self, title, *args):
list.__init__(self, *args)
self.title= title
def __repr__(self):
return 'FormPart(%r, %s)' % (self.title, list.__repr__(self))
现在,您可以说form=FormPart('My form',[question,FormPart…])
并使用普通列表索引和切片访问其中的问题和FormPart
接下来,一个问题可能是一个不变的东西,比如元组,但您可能希望其中的项具有良好的属性名称。因此,将其添加到元组中:
class FormQuestion(tuple):
def __new__(cls, title, details= '', answers= ()):
return tuple.__new__(cls, (title, details, answers))
def __repr__(self):
return 'FormQuestion%s' % tuple.__repr__(self)
title= property(operator.itemgetter(0))
details= property(operator.itemgetter(1))
answers= property(operator.itemgetter(2))
现在,您可以定义数据,如:
form= FormPart('MyForm', [
FormQuestion('Question 1', 'Why?', ('Because', 'Why not?')),
FormPart('Part 1', [
FormQuestion('Question 1.1', details= 'just guess'),
]),
FormPart('Part 2', [
FormQuestion('Question 2.1'),
FormPart('SubPart 1', [
FormQuestion('Question 2.1.1', answers= ('Yes')),
]),
]),
FormQuestion('Question 2'),
])
并访问它:
>>> form[0]
FormQuestion('Question 1', 'Why?', ('Because', 'Why not?'))
>>> form[1].title
'Part 1'
>>> form[2][1]
FormPart('SubPart 1', [FormQuestion('Question 2.1.1', '', 'Yes')])
现在,您可以在FormPart
上定义层次结构:
def getQuestions(self):
for child in self:
for descendant in child.getQuestions():
yield descendant
在表单问题上
:
def getQuestions(self):
yield self
现在您有了一个返回FormQuestions的后代生成器:
>>> list(form[1].getQuestions())
[FormQuestion('Question 1.1', 'just guess', ())]
>>> list(form.getQuestions())
[FormQuestion('Question 1', 'Why?', ('Because', 'Why not?')), FormQuestion('Question 1.1', 'just guess', ()), FormQuestion('Question 2.1', '', ()), FormQuestion('Question 2.1.1', '', 'Yes'), FormQuestion('Question 2', '', ())]
我想分享一下我从使用ElementTree中学到的一些东西,特别是lxml实现ElementTree和lxml.objectify。XML还可以简化为
和
标记,其名称存储为属性
questions.xml
<myform>
<question1>Question 1</question1>
<part1 name="Part 1">
<question1_1>Question 1.1</question1_1>
</part1>
<part2 name="Part 2">
<question2_1 attribute="stuff">Question 2.1</question2_1>
<subpart1 name="SubPart 1">
<question2_1_1>Question 2.1.1</question2_1_1>
<question2_1_2>Question 2.1.2</question2_1_2>
</subpart1>
</part2>
<question2>Question 2</question2>
</myform>
我想分享一下我从使用ElementTree中学到的一些东西,特别是lxml实现ElementTree和lxml