2011-01-11 3 views
3

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

[section] 
a = 10 
b = 15 
c = a-5 
d = b+c 

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

Если в ConfigParser нет возможности, вы можете рекомендовать какой-либо модуль?

+5

расчеты не какие конфигурационные файлы для. – SilentGhost

+1

@SilentGhost: вам не нужно делать слишком много обработки, но бывают ситуации, когда вы хотите сказать «x is 5 больше, чем y», имея возможность изменить y. Это намного опрятно, чем указание x_ydiff и сортировка правил приоритета и т. Д. –

+0

Вы можете использовать модуль '' config 'Vinay Sajip '(http://www.red-dove.com/config-doc), который был его записью в comp.lang.python [ConfigParserShootout] (http: // wiki. python.org/moin/ConfigParserShootout), который позволяет [использовать выражения] (http://www.red-dove.com/config-doc/#using-expressions) в файлах конфигурации. В качестве альтернативы вы могли бы с легкостью связать их с помощью [SimpleCalc.py] Стивена Сива (http://pyparsing.wikispaces.com/file/view/SimpleCalc.py) из [pyparsing-Examples] (http: // pyparsing. wikispaces.com/Examples). – martineau

ответ

9

Зачем использовать ConfigParser? Почему бы просто не

config.py:

a = 10 
b = 15 
c = a-5 
d = b+c 

script.py:

import config 
print(config.c) 
# 5 
print(config.d) 
# 20 
2

Один подход, что некоторые проекты используют, чтобы сделать ваш файл конфигурации модуль Python. Затем просто импортируйте его (или используйте exec) для запуска содержимого. Это дает вам много силы, хотя, очевидно, есть некоторые проблемы с безопасностью в зависимости от того, где вы его используете («просто вставьте эти строки в свой файл .whateverrc.py ...»).

+0

Одним из преимуществ использования 'exec' является то, что файл может иметь любое расширение или без него. Я считаю, что его нужно называть * .py для импорта. – martineau

+0

@martineau: Он также не должен находиться в PYTHONPATH. Новая система конфигов IPython использует 'exec' (хотя в файле все еще есть расширение .py, не в последнюю очередь, чтобы было ясно, что это такое). –

2

Если вы должны вы можете сделать что-то вроде этого:

example.conf:

[section] 
a = 10 
b = 15 
c = %(a)s+%(b)s 
d = %(b)s+%(c)s 

и в сценарии вы можете сделать:

import ConfigParser 

config = ConfigParser.SafeConfigParser() 
config.readfp(open('example.conf')) 

print config.get('section', 'a') 
# '10' 
print config.get('section', 'b') 
# '15' 
print config.get('section', 'c') 
# '10+15' 
print config.get('section', 'd') 
# '15+10+15' 

и вы можете Eval выражение :

print eval(config.get('section', 'c')) 
# 25 
print eval(config.get('section', 'd')) 
# 40 

Если я могу предложить я думаю, что ConfigParser модули классов отсутствуют функции, как это, я думаю, что метод get() должен позволить передать функцию, которая будет Eval выражение:

def my_get(self, section, option, eval_func=None): 

    value = self.get(section, option) 
    return eval_func(value) if eval_func else value 

setattr(ConfigParser.SafeConfigParser, 'my_get', my_get) 


print config.my_get('section', 'c', eval) 
# 25 

# Method like getint() and getfloat() can just be writing like this: 

print config.my_get('section', 'a', int) 
# 10 
+0

Случайный вызов eval в настройках вашего конфигурационного файла, вероятно, не является привычкой вступать.Файл python, который вы можете ожидать быть исполняемым, но вы не ожидаете, что будете выполнять произвольные инструкции изнутри файлов конфигурации. –

+0

Хотя мне нравится вся идея полу-исполняемых конфигурационных файлов, мне не очень-то нужно для обозначения '% (...) s' этого подхода. – martineau