Check if string can be evaluated (with eval()) in Python

时间:2015-07-15 07:18:48

标签: python eval

I know that I can try-except with the eval itself, but I want to use it in list_comprehensions or map:

[eval(x) if isevaluable(x) else x for x in some_list]

My driving to do so: I get argument from sys.argv - which can be int\float\built-in-constants (especially True, False, None). I want to casting them all in a simple & clean way.

[Note: safe-eval isn't the issue here (even it's indeed recommended)]

2 个答案:

答案 0 :(得分:1)

一个明显的解决方案,可能适用于您的特定eval字符串,也可能不适用。

def isevaluable(s):
    try:
        compile(s, "bogusfile.py", "exec")
        return True
    except:
        return False

这会编译代码,检查语法错误等。 不会捕捉到所有的逻辑问题,但它会在将其编入eval之前检查程序问题,这可能会导致各种麻烦。

我想到了:

def isevaluable(s):
    try:
        eval(s)
        return True
    except:
        return False

但是请记住,然后你会执行你的字符串,这可能会使你的结果变得模糊不清 例如,如果您的字符串为rm /tmp/cache.txt,则会在isevaluable中产生肯定结果,而[eval(x) ...]中会显示否定结果,因为它已在try语句中删除。

在这种情况下,compile()是更好的选择。它可能是任何一个例子。

答案 1 :(得分:0)

首先,如果你的x只包含一个字面值,字符串,数字,元组,列表,字符串,布尔值和无 - 你可以使用ast.literal_eval,这样更安全比eval()函数。

  

<强> ast.literal_eval(node_or_string)

     

安全地评估表达式节点或包含Python文字或容器显示的Unicode或Latin-1编码字符串。提供的字符串或节点可能只包含以下Python文字结构:字符串,数字,元组,列表,dicts,布尔值和None。

此外,您很可能必须自己定义函数isevaluatable(),例如 -

def isevaluatable(s):
    import ast
    try:
        ast.literal_eval(s)
        return True
    except ValueError:
        return False

然后你可以做

导入ast [ast.literal_eval(x)if isevaluatable(x)else x for some_list]

更简单的方法是让函数返回所需的值

def myeval(s):
    import ast
    try:
        return ast.literal_eval(s)
    except ValueError:
        return s

然后再做 -

[myeval(x) for x in some_list]