Python: Считайте конфигурационный файл с несколькими строками на ключ

Я пишу маленький набор тестов DB, который читает конфигурационные файлы с запросами и ожидаемыми результатами, например:

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-запросы могли бы содержать =
  • Я не представляю себе идею вызвать "s вокруг правой стороны, потому что существует много существующих файлов без него.

Править:

ConfigParser является большим, но он вынуждает меня добавить пространство или вкладку в начале каждой строки в многострочной записи. Это могло бы быть большой болью.

Заранее спасибо,

Adam

11
задан Adam Matan 11 February 2010 в 18:32
поделиться

3 ответа

Это почти тот самый вариант использования, который заставил нас перейти на YAML ( Википедия , реализация python , документация ; в качестве альтернативы вы можете посмотреть JSON ). YAML имеет некоторые преимущества перед configparser или json :

  • удобочитаемость (лучше, чем 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';
10
ответ дан 3 December 2019 в 03:35
поделиться

Модуль стандартной библиотеки 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')
16
ответ дан 3 December 2019 в 03:35
поделиться

Я бы посоветовал вам использовать регулярное выражение ... Код может выглядеть так, чтобы дать вам начало:

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

Надеюсь, это поможет!

С уважением, Кристоф

1
ответ дан 3 December 2019 в 03:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: