Python:读取每个键有多行的配置文件
我正在写一个小的数据库测试工具,它会读取配置文件,这些文件里有查询语句和预期的结果,比如:
query = "SELECT * from cities WHERE name='Unknown';"
count = 0
level = 1
name = "Check for cities whose name should be null"
suggested_fix = "UPDATE cities SET name=NULL WHERE name='Unknown';"
这个方法很好用;我用Python的 string.partition('=')
来分割每一行。
但我遇到的问题是,SQL查询语句太长了。目前我只是把这些查询写成一行,这样看起来很难看,也不方便维护。
我想找到一种优雅的、符合Python风格的方法来读取表达式右边的内容,即使它跨越多行也没关系。
注意:
- 我的SQL查询可能会包含
=
符号 - 我不太喜欢在右边内容周围强制加上
"
符号,因为很多现有的文件里没有这个。
补充:
ConfigParser 很不错,但它要求我在多行条目的每一行开头加一个空格或制表符,这可能会很麻烦。
提前谢谢你,
亚当
4 个回答
1
我建议你使用正则表达式……代码可能看起来像这样,给你一个开始的参考:
import re
test="""query = "select * from cities;"
count = 0
multine_query = "select *
from cities
where name='unknown';"
"""
re_config = re.compile(r'^(\w+)\s*=\s*((?:".[^"]*")|(?:\d+))$', re.M)
for key, value in re_config.findall(test):
if value.startswith('"'):
value = value[1:-1]
else:
value = int(value)
print key, '=', repr(value)
这个例子的输出是:
~> python test.py
query = 'select * from cities;'
count = 0
multine_query = "select *\nfrom cities\n where name='unknown';"
希望这对你有帮助!
祝好,
Christoph
24
Python的标准库模块ConfigParser默认就支持这个功能。配置文件需要按照一种标准格式来写:
[Long Section]
short: this is a normal line
long: this value continues
in the next line
上面的配置文件可以用下面的代码来读取:
import ConfigParser
config = ConfigParser.ConfigParser()
config.read('longsections.cfg')
long = config.get('Long Section', 'long')
11
这几乎正是我们决定使用YAML的原因之一。你可以在维基百科上了解更多,或者查看Python的实现和文档。另外,你也可以看看JSON,它也是一个不错的选择。YAML相比于configparser
或json
有一些优点:
- 人类可读性更强(对于较大的文件,YAML比JSON更好);
- 可以序列化任意的Python对象(这使得它和
pickle
一样不太安全,不过在Python的实现中有一个safe_load
函数可以缓解这个问题)。这对于像datetime
这样的简单对象来说已经很有用了。
为了全面起见,主要的缺点(个人观点)有:
- Python的实现比JSON的实现慢很多;
- 在不同平台之间的可移植性不如JSON。
举个例子
import yaml
sql = """
query : "SELECT * from cities
WHERE name='Unknown';"
count : 0
level : 1
name : "Check for cities whose name should be null"
suggested_fix : "UPDATE cities SET name=NULL WHERE name='Unknown';"
"""
sql_dict = yaml.safe_load(sql)
print(sql_dict['query'])
输出
SELECT * from cities WHERE name='Unknown';