好吧,如果您准备假设[process]
总是先于[export]
,并且[export]
将始终标记 Python 代码的结尾,那么您可以预处理 ini 文件以删除该部分,然后再将其传递给ConfigParser
.. .
from ConfigParser import RawConfigParser
from StringIO import StringIO
START_PROCESS_TOKEN = '[process]'
END_PROCESS_TOKEN = '[export]'
def hacky_parse(stream):
state = 0
ini_io = StringIO()
python_io = StringIO()
for line in stream.readlines():
if state == 0:
if line.strip() == START_PROCESS_TOKEN:
state = 1
continue
ini_io.write(line)
elif state == 1:
if line.strip() == END_PROCESS_TOKEN:
ini_io.write(line)
state = 2
continue
python_io.write(line)
else:
ini_io.write(line)
ini_io.seek(0)
python_io.seek(0)
config_parser = RawConfigParser()
config_parser.readfp(ini_io)
python_code = python_io.getvalue()
return config_parser, python_code
cfg = """
[load]
files=a,b,c
[process]
while 1:
do_stuff()
[export]
files=x,y,z
"""
my_stream = StringIO(cfg)
config_parser, process_code = hacky_parse(my_stream)
print 'The value of "files" in section "load" is...'
print config_parser.get('load', 'files')
print
print 'The raw Python code is...'
print process_code
...产生...
The value of "files" in section "load" is...
a,b,c
The raw Python code is...
while 1:
do_stuff()
...显然,my_stream
用类似...的东西代替真实的文件对象
my_stream = open('config.ini', 'r')
更新
好吧,您的代码更有可能被破坏,例如,如果该行[load]
出现在 Python 代码中。
我只是想到了另一种选择。如果您使配置文件看起来像 RFC822 消息...
Load-Files: a,b,c
Export-Files: x,y,z
# Python code starts here
while 1:
do_stuff()
...您可以像这样简单地解析它...
import email
cfg = \
"""Load-Files: a,b,c
Export-Files: x,y,z
# Python code starts here
while 1:
do_stuff()
"""
msg = email.message_from_string(cfg)
print msg.items()
print
print msg.get_payload()
..产生...
[('Load-Files', 'a,b,c'), ('Export-Files', 'x,y,z')]
# Python code starts here
while 1:
do_stuff()
我的意思是,您不必使用严格的 RFC822 格式,但是将 Python 代码放在配置文件末尾的好处是代码中的任何内容都不会与您在其余部分中使用的格式发生冲突的文件。