Python:读取每个键多行的配置文件

时间:2010-02-11 16:06:43

标签: python configuration-files text-parsing 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';"

效果很好;我使用Python的string.partition('=')来划分每一行。

我的问题是SQL查询很长。目前,我只是将这些查询粘贴为单行,这是丑陋且无法维护的。

我希望找到一种优雅的Pythonic方式来阅读表达的权利,即使跨越多行。

注意:

  • 我的SQL查询可能包含=
  • 我不喜欢在右侧强制"的想法,因为有许多没有它的现有文件。

修改

ConfigParser很棒,但它强迫我在多行条目的每一行的开头添加一个空格或制表符。这可能是一个巨大的痛苦。

提前致谢,

亚当

3 个答案:

答案 0 :(得分:15)

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')

答案 1 :(得分:10)

这几乎就是让我们切换到YAMLWikipediapython implementationdocumentation的用例;您可能希望查看{{3} } 作为备选)。与JSONconfigparser相比,YAML有一些优势:

  • 人类可读性(对于较大的文件,优于JSON);
  • 可以序列化任意python对象(这使得它与pickle一样不安全,但在python实现中有一个safe_load函数来缓解这个问题)。这对于像datetime对象这样简单的事情已经很有用了。

为了完整起见,主要缺点(IMO):

  • 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';

答案 2 :(得分: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';"

希望有所帮助!

此致 克里斯托弗