使用eval()时如何防止出现大错误?

时间:2019-05-27 02:01:14

标签: python eval

我正在用Python做一个计算器,目前正试图防止程序在处理大量输入时崩溃。

我知道如何捕获错误的唯一方法是使用“ try”和“ except”,所以我这样写:

def solve(self, equation):
    try:
        return eval(equation)
    except(OverflowError):
        messagebox.showinfo("Error","Result too large")
    return equation

(我知道eval可能很危险,但是用户无法键入任何输入,所以我认为很好)

当我用科学记法输入大量数字时,例如'389e+10**(58)*9'OverflowError被成功捕获,但是如果输入'55555555**5555555'之类的窗口,则窗口将停止响应。

我的印象是后者也会引发一个OverflowError,但我现在想这是可能发生的,因为它根本不会产生错误,eval根本无法处理算出这么大的结果。

如果是这种情况,我认为我应该对答案的大小设置一个限制,但是我不确定如何决定这个限制。有什么建议吗?

2 个答案:

答案 0 :(得分:4)

在Python中,float通常是一个64位浮点数,可以容纳有限范围。高于该值的值将引发OverflowError。当389e+10返回float时,整个表达式389e+10**(58)*9也返回float

另一方面,55555555**5555555返回一个int。在Python中,int可以保存任意大的值,仅受内存限制。因此,发生的事情是Python试图计算一个很大的数字,这花费了一个非常非常长的时间。

通常来说,这不是一个容易解决的问题,因为您使用的是eval,因此您不了解方程式的确切性质。

我建议改为解析方程式,这样您就可以对其进行详细检查。然后,您可能无法在基数和指数都很大的情况下不执行幂计算。

(或者您可以对所有内容都使用浮点计算,这会影响精度,但是我认为对于一个简单的计算器而言,这并不重要,对吧?)

答案 1 :(得分:0)

由于正在计算55555555**5555555,因此它停止响应。它不会产生OverflowError,因为Python中的整数是任意精度的。它会越来越大,占用越来越多的内存,直到它使计算机瘫痪为止。