众所周知,使用eval()
存在潜在的安全风险,因此ast.literal_eval(node_or_string)
提倡使用
但是在python 2.7中,ValueError: malformed string
运行此示例时会返回:
>>> ast.literal_eval("4 + 9")
而在python 3.3中,此示例按预期工作:
>>> ast.literal_eval('4+9')
13
为什么它在python 3而不是python 2上运行?如何在不使用高风险eval()
函数的情况下在python 2.7中进行修复?
这在Python
2上不起作用的原因在于它的实现literal_eval
。当righth操作数为复数时,原始实现只对加法和减法执行数字求值。在语法上,必须将复数表示为文字,这在语法上是必需的。
这个改变在Python
3,以便它支持任何类型的有效的数字表达的是对加法和减法的任一侧。但是,的使用literal_eval
仍然仅限于加法和减法。
这主要是因为literal_eval
应该是一个将单个 常量
文字(表示为字符串)转换为Python对象的函数。有点像repr
简单内置类型的倒退。不包括实际的表达式评估,并且它与Python
3一起使用的事实只是其实现的一个不错的副作用。
为了评估实际的表达式而不必使用eval
(我们不想使用),我们可以编写自己的基于AST的表达式评估算法。这非常简单,尤其是对于数字的简单算术运算(例如,构建自己的计算器等)时。我们只需将字符串解析为AST,然后通过查看不同的节点类型并应用正确的操作来评估结果树。
像这样:
import ast, operator
binOps = {
ast.Add: operator.add,
ast.Sub: operator.sub,
ast.Mult: operator.mul,
ast.Div: operator.div,
ast.Mod: operator.mod
}
def arithmeticEval (s):
node = ast.parse(s, mode='eval')
def _eval(node):
if isinstance(node, ast.Expression):
return _eval(node.body)
elif isinstance(node, ast.Str):
return node.s
elif isinstance(node, ast.Num):
return node.n
elif isinstance(node, ast.BinOp):
return binOps[type(node.op)](_eval(node.left), _eval(node.right))
else:
raise Exception('Unsupported type {}'.format(node))
return _eval(node.body)
如您所见,此实现非常简单。当然,它还不支持指数运算和一些一元节点之类的更复杂的东西,但是添加它并不难。而且效果很好:
>>> arithmeticEval('4+2')
6
>>> arithmeticEval('4*1+2*6/3')
8
您甚至可以在以后介绍更复杂的内容(例如,函数调用,例如sin()
)。
问题内容: 使用uCanaccess检索保存在桌面中的数据库时出现错误。 我的代码如下: 导入java.util.Scanner; 导入java.sql。*; 公共类dbTest1 { } 我将很乐意为您解决此错误提供任何建议。 谢谢,文斯 问题答案: 好吧,首先,导入您的库(lib文件夹中的jar文件)。http://sourceforge.net/projects/ucanaccess/fil
问题内容: 我对这部分代码有疑问,我正在尝试在预订表中插入一条记录。我试图输入的值是(6,3,3,20/06/2018 00:00:00,400,2800.00,True,560.00) 我收到的错误如下, “从字符串转换日期和/或时间时转换失败。” 我已尽力研究此问题,但我不知道如何解决此问题。任何帮助表示赞赏。 问题答案: Okey,您的代码有一些问题。我将尝试按顺序解释所有这些内容。 首先,
编辑:感谢Preetam Kumar,这个问题已经解决,但错误现在在其他地方。当我再次尝试解组我的xml文件时,我收到这个错误,告诉我找不到元素: 然而,我给了xml文件到模式的正确路径,但是它似乎没有使用它...我不明白。 注意:我知道模式和xml标记在下面的示例中不完全匹配,我已经在我的文件中纠正了它。 最近,我不得不使用JAXB java库将一些XML文件解析为java对象。 我制作了一个X
问题内容: 我收到以下错误: 第一个字段是格式。 有任何想法吗? 谢谢。 问题答案: 当您将字符串值插入日期列时,则需要在使用函数期间将其转换为日期。使用此功能时,您将提供字符串的格式。 功能格式: 因此,您的查询将如下所示: 参见带有演示的SQL Fiddle
无法打印出格式错误弹出的结果。 尝试在没有getWaitingTime()和%-20d(最后一个)的情况下执行,它可以工作。 尝试执行1,并用getWaitingTime()替换seqNo,它可以工作。 不确定是什么错误。 它调用toString方法的部分。它从servicelist被称为。 至于错误是: JAVAutil。MissingFormatArgumentException:邮局的格式说
问题内容: 我正在尝试学习Python(更具体地讲3),并且遇到此错误: 我用谷歌搜索,发现需要指定数字: 而且不像该教程(来自lynda.com)实际上说的那样: 以下教程即时消息具有Python 3.1,即时消息使用3.2,而我读到的有关此错误的信息是,此错误仅发生在<3.1(3.0)中。他们在3.2中撤消了此操作,还是我做错了什么? 另外,说慢点;)从字面上看,这是我学习Python的第一个