从配置文件中读取布尔条件?

3 python configuration parsing json config

使用ConfigParser和从Python中的配置文件中读取条件的最佳方法是什么json?我想读类似的东西:

[mysettings]
x >= 10
y < 5
Run Code Online (Sandbox Code Playgroud)

然后将其应用于代码where xy定义的变量,条件将应用于x, y代码中的值.就像是:

l = get_lambda(settings["mysettings"][0])
if l(x):
  # do something
  pass
l2 = get_lambda(settings["mysettings"][1])
if l2(y):
  # do something
  pass
Run Code Online (Sandbox Code Playgroud)

理想情况下,我也想指定条件x + y >= 6.

必须有更好的方法,但想法是使用配置文件中的简单布尔表达式约束变量的值.

Luk*_*raf 5

这是一个使用Python本身作为描述配置文件的语言的示例:

config.py

mysettings = [
    lambda x: x >= 10,
    lambda y: y < 5,
]
Run Code Online (Sandbox Code Playgroud)

main.py

from config import mysettings

a = 42
b = 300

for i, condition in enumerate(mysettings):
    for value in (a, b):
        result = condition(value)
        print "condition %s for value %s is: %s" % (i, value, result)
Run Code Online (Sandbox Code Playgroud)

输出:

condition 0 for value 42 is: True
condition 0 for value 300 is: True
condition 1 for value 42 is: False
condition 1 for value 300 is: False
Run Code Online (Sandbox Code Playgroud)

这当然假设配置文件被认为是可信输入,因为通过执行condition(value)您将执行配置文件中定义的任何功能.

但是,无论你使用什么语言,我都没有看到任何方法:条件是表达式,因此是可执行代码.如果您希望最终得到一个可以在代码中使用的Python表达式,那么您迟早要评估该表达式.

编辑:

如果由于某种原因你真的不能使用Python,那么你可以使用JSON中的配置文件来实现它:

config.json

{
  "mysettings": {
    "color": "Blue",
    "expressions": [
      "x >= 10",
      "y < 5"
    ]
  },
  "other_settings": {
    "color": "red"
  }
}
Run Code Online (Sandbox Code Playgroud)

main.py

import json

x = 42
y = 300


def eval_expr(expr, values):
    result = eval(expr, values.copy())
    print "The expression '%s' evaluates to '%s' for the values %r" % (
                                                    expr, result, values)
    return result


f = open('config.json')
data = json.loads(f.read())
settings = data["mysettings"]

for expr in settings['expressions']:
    values = dict(x=x, y=y)
    eval_expr(expr, values)
Run Code Online (Sandbox Code Playgroud)

结果:

The expression 'x >= 10' evaluates to 'True' for the values {'y': 300, 'x': 42}
The expression 'y < 5' evaluates to 'False' for the values {'y': 300, 'x': 42}
Run Code Online (Sandbox Code Playgroud)

或者,更接近你的例子:

x = 1
y = 2
values = dict(x=x, y=y)

e1 = settings['expressions'][0]
if eval_expr(e1, values):
    # do something
    pass

e2 = settings['expressions'][1]
if eval_expr(e2, values):
    # do something else
    pass
Run Code Online (Sandbox Code Playgroud)

结果:

The expression 'x >= 10' evaluates to 'False' for the values {'y': 2, 'x': 1}
The expression 'y < 5' evaluates to 'True' for the values {'y': 2, 'x': 1}
Run Code Online (Sandbox Code Playgroud)


mar*_*eau 5

我不认为你想,或者需要,同时使用configparser json,因为它们都是通过自身就足够了.以下是如何使用每个方法:

假设您有一个来自可靠来源的配置文件,其中包含以下内容:

myconfig.ini

[mysettings]
other=stuff
conds=
    x >= 10
    y < 5
    x + y >= 6
Run Code Online (Sandbox Code Playgroud)

它可以像这样解析和使用:

from __future__ import print_function
try:
    import configparser
except ImportError:  # Python 2
    import ConfigParser as configparser

get_lambda = lambda expr: lambda **kwargs: bool(eval(expr, kwargs))

cp = configparser.ConfigParser()
cp.read('myconfig.ini')

exprs = cp.get('mysettings', 'conds').strip()
conds = [expr for expr in exprs.split('\n')]

l = get_lambda(conds[0])
l2 = get_lambda(conds[1])
l3 = get_lambda(conds[2])

def formatted(l, c, **d):
    return '{:^14} : {:>10} -> {}'.format(
        ', '.join('{} = {}'.format(var, val) for var, val in sorted(d.items())), c, l(**d))

l = get_lambda(conds[0])
print('l(x=42): {}'.format(l(x=42)))
print()
print(formatted(l, conds[0], x=42))
print(formatted(l2, conds[1], y=6))
print(formatted(l3, conds[2], x=3, y=4))
Run Code Online (Sandbox Code Playgroud)

这将导致以下输出:

l(x=42): True

    x = 42     :    x >= 10 -> True
    y = 6      :      y < 5 -> False
 x = 3, y = 4  : x + y >= 6 -> True
Run Code Online (Sandbox Code Playgroud)

如果信息保存在类似于以下的JSON格式文件中:

myconfig.json

{
    "mysettings": {
        "other": "stuff",
        "conds": [
          "x >= 10",
          "y < 5",
          "x + y >= 6"
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)

它可以很容易地用json模块解析并以类似的方式使用:

import json

with open('myconfig.json') as file:
    settings = json.loads(file.read())

conds = settings['mysettings']['conds']
Run Code Online (Sandbox Code Playgroud)

......其余部分将是相同的并产生相同的结果.即:

l = get_lambda(conds[0])
print('l(x=42): {}'.format(l(x=42)))
print()
print(formatted(l, conds[0], x=42))
print(formatted(l2, conds[1], y=6))
print(formatted(l3, conds[2], x=3, y=4))
Run Code Online (Sandbox Code Playgroud)