1.1.4 符号与数字

在数学中,即使读者还不知道a的值,也可以“设b=a2-a”,然后开始推导。在该语句中,不管a的值是什么,都可以用a来定义b

但如果你启动Python并立即输入等价的语句b=a**2-a,结果将是一条错误消息[3]。每次按下<Return>,Python都会尝试计算每个赋值语句的值。如果变量a还没有被赋值,则计算失败,Python会报错。虽然其他计算机数学包可以接受这样的输入,跟踪符号关系,并在以后对其进行计算,但原生Python是不能的[4]


[3] 符号**表示幂运算。见1.4.2节。

[4] SymPy库使Python中的符号计算成为可能。见10.3.2节。

“设b=a2-a”这样的定义将在整个讨论过程中保持不变,这是理所当然的。如果我们说,“在a=1的情况下……”,那么读者知道b等于零;如果我们稍后说,“在a=2的情况下……”,那么我们就不必重申b的定义,读者也会知道这个符号现在代表值22-2=2。

相反,像Python这样的数值系统在执行赋值b=a**2-a之后会忘记ba之间的任何关系。它只记得现在赋给b。如果后面改变a的值,b的值不会发生改变[5]


[5] 在数学中,语句b=a2-a本质上将b定义为a的函数。Python当然也可以实现这一点,方法是定义一个返回值为a2-a的函数并将该函数赋给名称b(见6.1节),但“=”的作用并非如此。

在数学证明过程中改变符号关系通常是不可取的。然而,在Python中,如果开始宣称b=a**2-a,那么没有什么能阻止后面把它改成b=2**a。第二个赋值语句丢弃了第一个赋值语句中计算的值,并用新计算的值替换它,从而更新了Python的状态。