当前位置: 首页 > 面试题库 >

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

阎麒
2023-03-14
问题内容

我正在用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

问题答案:

这应该做您想要的:

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)

例子:

$ ./SO_31999444.py 'elapsed > 30'
[2, 'runtime', {'jobname': 'high38854', 'elapsed': 45.6}]
[3, 'runtime', {'jobname': 'high38855', 'elapsed': 78.9}]
[6, 'runtime', {'jobname': 'high38858', 'elapsed': 36.9}]
[7, 'runtime', {'jobname': 'high38859', 'elapsed': 75.3}]


$ ./SO_31999444.py 'elapsed > 20' 'elapsed < 50'
[2, 'runtime', {'jobname': 'high38854', 'elapsed': 45.6}]
[5, 'runtime', {'jobname': 'high38857', 'elapsed': 25.8}]
[6, 'runtime', {'jobname': 'high38858', 'elapsed': 36.9}]


$ ./SO_31999444.py 'elapsed > 20' 'elapsed < 50' 'key >= 5'
[5, 'runtime', {'jobname': 'high38857', 'elapsed': 25.8}]
[6, 'runtime', {'jobname': 'high38858', 'elapsed': 36.9}]


$ ./SO_31999444.py "'9' in jobname"
[7, 'runtime', {'jobname': 'high38859', 'elapsed': 75.3}]


$ ./SO_31999444.py "jobname contains '9'"
[7, 'runtime', {'jobname': 'high38859', 'elapsed': 75.3}]


$ ./SO_31999444.py "jobname in ['high38857', 'high38858']"
[5, 'runtime', {'jobname': 'high38857', 'elapsed': 25.8}]
[6, 'runtime', {'jobname': 'high38858', 'elapsed': 36.9}]


$ ./SO_31999444.py "9 in jobname"
A literal in one of your conditionals is the wrong type. If you can't see it, try running each one separately.


$ ./SO_31999444.py "notakey == 'something'"
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.


$ ./SO_31999444.py "2 == 2"
[1, 'runtime', {'jobname': 'high38853', 'elapsed': 12.3}]
[2, 'runtime', {'jobname': 'high38854', 'elapsed': 45.6}]
[3, 'runtime', {'jobname': 'high38855', 'elapsed': 78.9}]
[4, 'runtime', {'jobname': 'high38856', 'elapsed': 14.7}]
[5, 'runtime', {'jobname': 'high38857', 'elapsed': 25.8}]
[6, 'runtime', {'jobname': 'high38858', 'elapsed': 36.9}]
[7, 'runtime', {'jobname': 'high38859', 'elapsed': 75.3}]


$ ./SO_31999444.py
[1, 'runtime', {'jobname': 'high38853', 'elapsed': 12.3}]
[2, 'runtime', {'jobname': 'high38854', 'elapsed': 45.6}]
[3, 'runtime', {'jobname': 'high38855', 'elapsed': 78.9}]
[4, 'runtime', {'jobname': 'high38856', 'elapsed': 14.7}]
[5, 'runtime', {'jobname': 'high38857', 'elapsed': 25.8}]
[6, 'runtime', {'jobname': 'high38858', 'elapsed': 36.9}]
[7, 'runtime', {'jobname': 'high38859', 'elapsed': 75.3}]

这是一个有趣的小项目:)。



 类似资料:
  • 问题内容: 我必须从D / B检索一组列值并将其作为条件进行检查。 例如,我将有像字符串,在d / B柱。(值是一直比较的值)。我将在代码中声明一个变量值,我应该评估这种情况。 我怎样才能做到这一点??任何帮助都受到赞赏。谢谢。 问题答案: 这是使用标准(Java 1.6+)脚本库的示例:

  • 我的bash脚本接收一个字符串形式的文件名(或相对路径),但是必须从该文件中读取。如果我在脚本中将文件名直接声明为文字(没有引号),我就只能从文件名中读取...这对于参数来说是不可能的,因为它们一开始就是隐式字符串。观察: 产量: 如上所述,我无法将命令行参数传递给上述例程,因为我得到的行为与引用字符串上的行为相同。

  • 问题内容: 当用户登录时,我正在设置一个sessionScope对象,并且那个bean对象由几个其他bean组成。这些bean的属性之一是枚举,但是我发现EL无法获取enum类的属性,而只能获取Java bean对象的属性。因此,我决定为该枚举创建一个bean类,并将该枚举嵌套在该bean类中。我为替换枚举而制作的java bean,以便可以通过EL获得其值,如下所示: 但是,当我尝试访问等级名称

  • 问题内容: 我有一个将存储Number对象的列表。该列表将通过分析字符串列表来填充,其中每个字符串都可以表示Number的任何子类。 如何将字符串解析为通用数字,而不是特定的整数或浮点数? 问题答案: 数字不能实例化,因为它是抽象类。我建议传入数字,但是如果您设置为字符串,则可以使用任何子类来解析它们, 要么 @请参阅NumberFormat

  • 问题内容: 我在文本框上使用MS AJAX AutoCompleteExtender。除Web服务返回类似“ 0010”的字符串(在这种情况下,它显示为“ 8”)外,它都工作正常。 我最终意识到它是将字符串“ 0010”解释为八进制数字(然后通过添加诸如“ 0100”和“ 0x10”之类的字符串来证明这一点。) 我该如何预防?如果Web服务返回“ 0010”,则我希望自动完成扩展程序也显示“ 00

  • 问题内容: 我正在制作一种方法来读取整个类代码并对其进行一些处理。 我想要做的是获取方法的名称,并使用它创建一个字符串。 像removeProduct这样的东西 我将创建一个字符串“删除产品” 在大写情况下如何拆分名称方法?如何用每个单词的第一个字母作为大写字母来构建这个新字符串?我正在使用子字符串,是否有更简便更好的方法呢? ps:我确定我的巴西英语对标题没有帮助。如果有人能让它看起来更好,我将

  • 问题内容: 我正在使用以下代码从外部程序获取标准输出: 方法返回一个字节数组: 但是,我想将输出作为普通的字符串使用。这样我就可以像这样打印它: 我认为这就是方法的用途,但是当我尝试使用它时,我又得到了相同的字节数组: 如何将字节值转换回字符串?我的意思是,使用”batteries”而不是手动进行操作。我希望它与Python 3兼容。 问题答案: 你需要解码bytes对象以产生一个字符串:

  • 问题内容: 熊猫的read_csv()方法将’NA’解释为nan(不是数字),而不是有效的字符串。 在下面的简单情况下,请注意,第1行第2列(基于零的计数)的输出为’nan’而不是’NA’。 sample.tsv (制表符分隔) PDB链SP_PRIMARY RES_BEG RES_END PDB_BEG PDB_EN​​D SP_BEG SP_END 5d8b N P60490 1146 114