一条语句中有两个不同的错误时,Python如何确定要显示哪个错误?

时间:2019-01-12 20:36:17

标签: python-3.x

在解释器中键入以下内容:

10(b)

我们收到未定义b的NameError。但是,当我们尝试:

10(4)

现在,我们收到错误消息,指出int是不可调用的。为什么Python在上述第一种情况下没有给出相同的错误,因为即使在那里,int也不能被调用?换句话说,在第一个代码段中,我们同时存在“无法调用”和“ NameError”两个错误。如果Python从左到右扫描,它将首先看到在int(10)上执行的调用操作。因此,它也应该为第一个给出“ int not callable”错误。为什么不呢?

我认为这可能是因为它首先评估括号内的表达式。但是,当我们尝试这样做时:

f(print("Hello"))

现在,它说NameError未定义f。它甚至不打印“ Hello”。因此,这表明我们对带括号的表达式求值的假设似乎不成立。

那么它到底如何工作?

1 个答案:

答案 0 :(得分:3)

您只是在执行有效的表达式,这些表达式有运行时错误。该代码在stated evaluation order中用运算符executed according to their precedence执行。在每个表达式中,您需要查看该特定操作的文档以查看操作各部分的执行顺序。

在所有三种情况下,您都要求Python执行call,并记录了规则:

  

主要对象必须求值为可调用对象[。]在尝试调用之前,将评估所有参数表达式。

可调用对象首先被评估为对象 ,然后10成功执行以生成一个对象。在计算完参数表达之前,尚未尝试调用。

参数表达式是构成要传递给调用的值的表达式,(...)中的位。只有对这些表达式求值后,才会进行调用。

您的第一个示例给出了NameError异常,因为b表达式求值失败。 Python从未执行过该调用,因为对参数表达式的求值失败。

在第二个示例中,参数表达式为4,这是一个成功的有效表达式,因此只有这样Python才能继续执行调用。但是10是不可调用的,因此是下一个失败。

最后一个示例在f表达式的开头就失败了,因为Python首先评估了可调用部分,但由于未定义名称而无法加载可调用部分。

对于其他操作员,将应用不同的评估顺序规则,您必须查看该特定操作员的文档,以了解组成零件将按什么顺序执行。