在解释器中键入以下内容:
10(b)
我们收到未定义b的NameError。但是,当我们尝试:
10(4)
现在,我们收到错误消息,指出int是不可调用的。为什么Python在上述第一种情况下没有给出相同的错误,因为即使在那里,int也不能被调用?换句话说,在第一个代码段中,我们同时存在“无法调用”和“ NameError”两个错误。如果Python从左到右扫描,它将首先看到在int(10)上执行的调用操作。因此,它也应该为第一个给出“ int not callable”错误。为什么不呢?
我认为这可能是因为它首先评估括号内的表达式。但是,当我们尝试这样做时:
f(print("Hello"))
现在,它说NameError未定义f。它甚至不打印“ Hello”。因此,这表明我们对带括号的表达式求值的假设似乎不成立。
那么它到底如何工作?
答案 0 :(得分:3)
您只是在执行有效的表达式,这些表达式有运行时错误。该代码在stated evaluation order中用运算符executed according to their precedence执行。在每个表达式中,您需要查看该特定操作的文档以查看操作各部分的执行顺序。
在所有三种情况下,您都要求Python执行call,并记录了规则:
主要对象必须求值为可调用对象[。]在尝试调用之前,将评估所有参数表达式。
可调用对象首先被评估为对象 ,然后10
成功执行以生成一个对象。在计算完参数表达之前,尚未尝试调用。
参数表达式是构成要传递给调用的值的表达式,(...)
中的位。只有对这些表达式求值后,才会进行调用。
您的第一个示例给出了NameError
异常,因为b
表达式求值失败。 Python从未执行过该调用,因为对参数表达式的求值失败。
在第二个示例中,参数表达式为4
,这是一个成功的有效表达式,因此只有这样Python才能继续执行调用。但是10
是不可调用的,因此是下一个失败。
最后一个示例在f
表达式的开头就失败了,因为Python首先评估了可调用部分,但由于未定义名称而无法加载可调用部分。
对于其他操作员,将应用不同的评估顺序规则,您必须查看该特定操作员的文档,以了解组成零件将按什么顺序执行。