将Python字符串解释为条件语句?

将Python字符串解释为条件语句?,python,Python,我正在用python处理一些json格式的日志文件。编写一些条件查询代码非常简单,例如 line=[1,'runtime',{'elapsed':12.3,'jobname':'high38853'}] # read from json # split the record and see what jobs take over 30 seconds key,category,details=line if category == 'runtime' and details['elapsed

我正在用python处理一些json格式的日志文件。编写一些条件查询代码非常简单,例如

line=[1,'runtime',{'elapsed':12.3,'jobname':'high38853'}]  # read from json

# split the record and see what jobs take over 30 seconds
key,category,details=line
if category == 'runtime' and details['elapsed'] > 30:
    print details
是否有一种方法可以安全地将字符串解释为条件表达式的一部分,这样我就可以在命令行上接受条件并将其作为查询的一部分

search 'details["elapsed"] > 30'
所以在代码中我可以做这样的事情

 if *something involving sys.argv[1]*:
     print line

这并不是一个真正安全的方法。对于基本条件,可以解析特定格式的输入字符串。如果您的输入格式为“var>5”,您可以这样解析它:

var, op, num = argv[1].split()
var = getattr(sys.modules[__name__], var) # Get a reference to the data
num = int(num)
if op == ">":
   r = var > num
elif op == "<":
   r = var < num
...

if r:
    <do stuff>
var,op,num=argv[1].split()
var=getattr(sys.modules[\uuuuu name\uuuu],var)#获取对数据的引用
num=int(num)
如果op==“>”:
r=var>num

elif op==“这应该是您想要的:

from __future__ import print_function

import ast
import operator
import sys

OPERATORS = {
    '<': operator.lt,
    '<=': operator.le,
    '>': operator.gt,
    '>=': operator.ge,
    '==': operator.eq,
    '!=': operator.ne,
    # 'in' is using a lambda because of the opposite operator order
    # 'in': (lambda item, container: operator.contains(container, item),
    'in': (lambda item, container: item in container),
    'contains': operator.contains,
    }


def process_conditionals(conditional_strings, variables):
    for conditional_string in conditional_strings:
        # Everything after first and op is part of second
        first, op, second = conditional_string.split(None, 2)

        resolved_operands = []
        for raw_operand in (first, second):
            try:
                resolved_operand = ast.literal_eval(raw_operand)
            except ValueError:  # If the operand is not a valid literal
                ve = sys.exc_info()
                try:
                    # Check if the operand is a known value
                    resolved_operand = variables[raw_operand]
                except KeyError:  # If the operand is not a known value
                    # Re-raise the ValueError
                    raise ve[1], None, ve[2]

            resolved_operands.append(resolved_operand)

        yield (op, tuple(resolved_operands))


def main(lines, *conditional_strings):
    for line in lines:
        key, category, details = line

        variables = {
            'key': key,
            'category': category,
            'elapsed': details['elapsed'],
            'jobname': details['jobname'],
            }

        conditionals = process_conditionals(conditional_strings, variables)

        try:
            # You could check each conditional separately to determine
            # which ones have errors.
            condition = all(OPERATORS[op](*operands)
                            for op, operands in conditionals)
        except TypeError:
            print("A literal in one of your conditionals is the wrong type. "
                  "If you can't see it, try running each one separately.",
                  file=sys.stderr)
            break
        except ValueError:
            print("An operand in one of your conditionals is neither a known "
                  "variable nor a valid literal. If you can't see it, try "
                  "running each one separately.", file=sys.stderr)
            break
        else:
            if condition:
                print(line)


if __name__ == '__main__':
    lines = [
        [1, 'runtime', {'elapsed': 12.3, 'jobname': 'high38853'}],
        [2, 'runtime', {'elapsed': 45.6, 'jobname': 'high38854'}],
        [3, 'runtime', {'elapsed': 78.9, 'jobname': 'high38855'}],
        [4, 'runtime', {'elapsed': 14.7, 'jobname': 'high38856'}],
        [5, 'runtime', {'elapsed': 25.8, 'jobname': 'high38857'}],
        [6, 'runtime', {'elapsed': 36.9, 'jobname': 'high38858'}],
        [7, 'runtime', {'elapsed': 75.3, 'jobname': 'high38859'}],
        ]

    conditional_strings = sys.argv[1:]

    main(lines, *conditional_strings)
from\uuuuu future\uuuuu导入打印功能
导入ast
进口经营者
导入系统
运算符={
“=”:operator.ge,
“=”:operator.eq,
“!=”:operator.ne,
#“in”使用lambda,因为运算符顺序相反
#'in':(lambda项,容器:operator.contains(容器,项),
'in':(lambda项目,容器:容器中的项目),
“包含”:运算符.contains,
}
def process_条件(条件字符串、变量):
对于条件字符串中的条件字符串:
#第一次和第二次之后的一切都是第二次的一部分
第一,op,second=条件字符串.split(无,2)
已解析的_操作数=[]
对于中的原始操作数(第一个,第二个):
尝试:
已解析的\u操作数=ast.literal\u eval(原始\u操作数)
ValueError除外:#如果操作数不是有效的文字
ve=sys.exc_info()
尝试:
#检查操作数是否为已知值
已解析操作数=变量[原始操作数]
KeyError除外:#如果操作数不是已知值
#重新提出错误
提高ve[1],无,ve[2]
解析的\u操作数。追加(解析的\u操作数)
产量(运算,元组(解析的_操作数))
def main(行,*条件_字符串):
对于行中的行:
关键字、类别、详细信息=行
变量={
“键”:键,
“类别”:类别,
“已用”:详细信息[“已用”],
“jobname”:详细信息[“jobname”],
}
条件=过程条件(条件字符串、变量)
尝试:
#您可以分别检查每个条件以确定
#哪些有错误。
条件=所有(运算符[op](*操作数)
对于op,条件中的操作数)
除类型错误外:
print(“某个条件语句中的文字类型错误。”
“如果看不到,请尝试分别运行每一个。”,
文件=sys.stderr)
打破
除值错误外:
print(“其中一个条件中的操作数既不是已知的”
变量或有效文本。如果看不到,请重试
“分别运行每一个。”,file=sys.stderr)
打破
其他:
如果条件:
打印(行)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
行=[
[1,'runtime',{'Appeased':12.3,'jobname':'high38853'}],
[2,'runtime',{'Appeased':45.6,'jobname':'high38854'}],
[3,'runtime',{'Appeased':78.9,'jobname':'high38855'}],
[4,'runtime',{'Appeased':14.7,'jobname':'high38856'}],
[5,'runtime',{'Appeased':25.8,'jobname':'high38857'}],
[6,'runtime',{'Appeased':36.9,'jobname':'high38858'}],
[7,'runtime',{'Appeased':75.3,'jobname':'high38859'}],
]
条件_strings=sys.argv[1:]
main(行,*条件字符串)
示例:

$。/SO_31999444.py“已用时间>30”
[2,'runtime',{'jobname':'high38854','appeased':45.6}]
[3,'runtime',{'jobname':'high38855','appeased':78.9}]
[6,'runtime',{'jobname':'high38858','appeased':36.9}]
[7,'runtime',{'jobname':'high38859','appeased':75.3}]
$./SO_31999444.py'经过时间>20''经过时间<50'
[2,'runtime',{'jobname':'high38854','appeased':45.6}]
[5,'runtime',{'jobname':'high38857','appeased':25.8}]
[6,'runtime',{'jobname':'high38858','appeased':36.9}]
$./SO_31999444.py'已用时间>20''已用时间<50''键>=5'
[5,'runtime',{'jobname':'high38857','appeased':25.8}]
[6,'runtime',{'jobname':'high38858','appeased':36.9}]
$./SO_31999444.py“'9'在jobname中”
[7,'runtime',{'jobname':'high38859','appeased':75.3}]
$./SO_31999444.py“jobname包含'9'”
[7,'runtime',{'jobname':'high38859','appeased':75.3}]
$./SO_31999444.py“jobname in['high38857','high38858']中的作业名”
[5,'runtime',{'jobname':'high38857','appeased':25.8}]
[6,'runtime',{'jobname':'high38858','appeased':36.9}]
$./SO_31999444.py“jobname中的9”
其中一个条件语句中的文字类型错误。如果看不到,请尝试分别运行每一个。
$./SO_31999444.py“notakey==‘某物’”
其中一个条件中的操作数既不是已知变量,也不是有效的文字。如果看不到,请尝试分别运行每个操作数。
$./SO_31999444.py“2==2”
[1,'runtime',{'jobname':'high38853','appeased':12.3}]
[2,'runtime',{'jobname':'high38854','appeased':45.6}]
[3,'runtime',{'jobname':'high38855','appeased':78.9}]
[4,'runtime',{'jobname':'high38856','appeased':14.7}]
[5,'runtime',{'jobname':'high38857','appeased':25.8}]
[6,'runtime',{'jobname':'high38858','appeased':36.9}]
[7,'runtime',{'jobname':'high38859','appeased':75.3}]
美元/苏31999444.py
[1,'runtime',{'jobname':'high38853','appeased':12.3}]
[2,'runtime',{'jobname':'high38854','appeased':45.6}]
[3,'runtime',{'jobname':'high38855','appeased':78.9}]
[4,'runtime',{'jobname':'high38856','appeased':14.7}]
[5,'运行时',{'