這聽起來像你後分層數據存儲...
這可能是值得探討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