Преобразование значений ConfigParser в типы данных Python - PullRequest
10 голосов
/ 02 июня 2011

ConfigParser требует, чтобы все секции, ключи и значения были строками; не удивительно. У него есть методы для преобразования значений в типы данных с getfloat, getint, getboolean. Если вы не знаете тип данных, вы можете заключить get() в eval(), чтобы получить строку, такую ​​как:

>>> from ConfigParser import SafeConfigParser
>>> cp = SafeConfigParser()
>>> cp.add_section('one')
>>> cp.set('one', 'key', '42')
>>> print cp.get('one', 'key')
'42'
>>> print eval(cp.get('one', 'key'))
42
>>> cp.set('one', 'key', 'None')
>>> print eval(cp.get('one', 'key'))
None
>>> 

Есть ли лучший способ? Я предполагаю, что существуют некоторые серьезные проблемы безопасности при оценке текста из файла, который я признаю; Я полностью доверяю файлу.

Я подумал, что для этого буду использовать pickle, но мне бы очень хотелось, чтобы файл конфигурации читался человеком.

Как бы вы это сделали?

Ответы [ 4 ]

13 голосов
/ 02 июня 2011

Если вы используете Python 2.6 или выше, вы можете использовать ast.literal_eval:

ast.literal_eval (node_or_string)
Безопасная оценкаузел выражения или строка, содержащая выражение Python.Предоставленная строка или узел может состоять только из следующих литеральных структур Python: строк, чисел, кортежей, списков, диктов, логических значений и None.

Это можно использовать для безопасной оценки строк, содержащих выражения Python из ненадежных источниковбез необходимости разбирать значения самостоятельно.

Это будет работать как eval, когда строка безопасна:

>>> literal_eval("{'key': 10}")
{'key': 10}

Но произойдет сбой, если что-либо, кроме перечисленных типовв документации появляются:

>>> literal_eval("import os; os.system('rm -rf somepath')")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/ast.py", line 49, in literal_eval
    node_or_string = parse(node_or_string, mode='eval')
  File "/usr/lib64/python2.6/ast.py", line 37, in parse
    return compile(expr, filename, mode, PyCF_ONLY_AST)
  File "<unknown>", line 1
    import os; os.system('rm -rf somepath')
         ^
SyntaxError: invalid syntax
3 голосов
/ 02 января 2015

Для тех, кто может искать другой более простой ответ, вместо того, чтобы самостоятельно преобразовывать типы данных, вы можете использовать модуль localconfig , который выполняет преобразование для вас. Преобразование выполняется путем угадывания типа данных на основе значения (т. Е. 123 - это int, 123.4 - это число с плавающей запятой, true - это тип bool и т. Д.).

Вот пример после ОП:

>>> from localconfig import config
>>> config.read('[one]\nkey = 42\nkey2 = None')
>>> config.one.key, type(config.one.key)
(42, <type 'int'>)
>>> config.one.key2, type(config.one.key2)
(None, <type 'NoneType'>)
>>> config.get('one', 'key'), config.get('one', 'key2')
(42, None)

Это оболочка поверх ConfigParser, поэтому она полностью совместима.

Проверьте это на https://pypi.python.org/pypi/localconfig

1 голос
/ 11 июля 2013

Если вы используете версию 2.7+, вы можете использовать методы .getint .getfloat .getbool. Вы можете узнать больше о них в документах

Так что ваше приложение будет использовать print cp.getint('one', 'key')

0 голосов
/ 10 февраля 2014

Checkout ConfigIt для дополнительных параметров конфигурации pythonic

https://github.com/barberj/ConfigIt

...