9

转向具有 C/Java 背景的 python,我最近不得不实现一个相互递归,但是 python 中的一些东西困扰着我:

由于一个python程序是逐行解释的,如果我在同一个python文件中一个接一个地有两个函数:

def A(n):
    B(n-1)
# if I add A(1) here, it gives me an error
def B(n):
    if n <= 0:
        return
    else:
        A(n-1)

当解释器正在阅读A时,B尚未定义,但是这段代码不会给我一个错误

我的理解是,当被解释时,python 会在一些本地名称空间中def添加一个条目,但对于函数体,它只进行语法检查:locals(){"function name": function address}

def A():
    blabla # this will give an error

def B():
    print x # even though x is not defined, this does not give an error
    A()     # same as above, NameError is only detected during runtime
4

3 回答 3

5

该行B(n-1)表示“执行此语句时,B在模块范围内查找某些函数,然后使用参数调用它n-1”。由于查找发生在函数执行时,B因此可以稍后定义。

B(此外,您可以用不同的函数完全覆盖,然后A调用新函数B。但这可能会导致一些混乱的代码。)

如果您担心无法捕获对不存在函数的调用,可以尝试使用静态分析工具。除此之外,请确保您正在测试您的代码。

于 2015-10-08T21:56:33.103 回答
4

ASyntaxError将在编译时被捕获,但大多数其他错误(NameError,ValueError等)只会在运行时被捕获,并且只有在调用该函数时才会被捕获。

“如果我写了一个函数,如果它没有在我的测试中被调用......” - 这就是你应该测试一切的原因。

一些 IDE 会在各种情况下发出警告,但最好的选择仍然是自己进行彻底的测试。这样,您还可以检查由用户输入等因素引起的错误,IDE 的自动检查不会涵盖这些错误。

于 2015-10-08T21:57:19.513 回答
0

当解释器读取 A 时,B 尚未定义,但是这段代码没有给我错误

python解释器不报错的原因可以从docs中找到,技术上称为前向引用:

自由变量的名称解析发生在运行时,而不是编译时。

于 2016-05-29T13:42:06.447 回答