这听起来像你后分层数据存储...
这可能是值得探讨XML and XPaths,正好有个想想你的情况,并熟悉一些概念。
用JSON也可以做到这一点,使用类似JSONPath的东西 - 但我建议首先使用XML/XPath,因为它更清晰一些,是一种更成熟的技术。
这是诸如此类的事情的演示中,我脑子里想的:
text.xml
:
<root>
<condition var_name="number" op="not-equal" value="42">
<condition var_name="name" op="equal" value="arthur">
<result var_name="number" value="42"/>
</condition>
</condition>
<condition op="default">
<condition var_name="name" op="equal" value="zaphod">
<result var_name="number" value="0"/>
</condition>
</condition>
</root>
#!/usr/bin/env python3
from pprint import pprint
import xml.etree.ElementTree as ET
# the <conditional> operations
ops = {
'equal': lambda data, var_name, value: data[var_name] == value,
'not-equal': lambda data, var_name, value: data[var_name] != value,
}
def el_get(el, attr_name):
value = el.get(attr_name)
try:
value = int(value) # try to force numerics for the demo...
except:
pass
return value
def dig(root, data):
# get any results, and apply them to the data
for el in root.findall('./result[@var_name][@value]'):
var_name = el_get(el, 'var_name')
value = el_get(el, 'value')
if var_name not in data:
raise Exception('bad var_name (%s)' % (var_name))
data[var_name] = value
# run through the conditions, running with the first that matches
for el in root.findall('./condition[@var_name][@op][@value]'):
op = el_get(el, 'op')
if op not in ops:
raise Exception('bad operation (%s)' % (op))
var_name = el_get(el, 'var_name')
value = el_get(el, 'value')
if var_name not in data:
raise Exception('bad var_name (%s)' % (var_name))
result = ops[op](data, var_name, value)
if result is True:
dig(el, data)
return
# run through the defaults, taking the first
for el in root.findall('./condition[@op="default"]'):
dig(el, data)
return
return
# grab the XML
root = ET.parse('test.xml').getroot()
# process & print
data = { 'number': 21, 'name': 'arthur' }
dig(root, data)
pprint(data) # pass
# process & print
data = { 'number': 21, 'name': 'zaphod' }
dig(root, data)
pprint(data) # pass
# process & print
data = { 'number': 42, 'name': 'arthur' }
dig(root, data)
pprint(data) # pass
# process & print
data = { 'number': 42, 'name': 'zaphod' }
dig(root, data)
pprint(data) # pass
为什么不把它作为Python和进口? – zondo
如果您将它存储为某种.py文件,该怎么办;)。真的虽然在这里想要系列化是合理的吗? – gbtimmon
我同意上面的评论,但是在你的例子中,你需要为每个条件使用一个对象数组,以便在反序列化时保留顺序。最好将所有重要数据存储为*值*,并将键保存为这些值的描述符。 – Julien