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)]
答案 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]