Python 函数声明先后顺序的问题!

在 Python 中如果把函数定义写在调用的下方可能会出错,例如下面的代码

foo()
def foo():      print("hello")

执行时会报出错误

Python资源共享群:484031800

NameError: name 'foo' is not defined

这时候要把 foo() 调用代码放到该函数的声明后面

def foo():      print("hello")
foo()

这样执行就一切正常了。这仿佛像是 C 语言中的函数调用需要提前声明一般,例如在 C 语言中要调用后头的定义的函数要写成

void foo();
 
int main() {
    foo();
}
 
void foo() {
    printf("Hello");
}

实际上 Python 中并不存在函数提前声明一说,也不能像 Java 那样函数可以写在任意位置,因为 Java 是编译型的语言,Python 是解释型的。

而且也不是一定要求被调用的函数一定要在源代码层面上定义在调用者前方。

Python 中函数声明的顺序据我理解有两条规则

  1. Python 源代码是由上往下解析的
  2. 找到程序入口(未包含在函数中的代码) 即开始执行,执行到的函数未被先行解释到即报错

分析下面两段代码

def foo():
    bar()
 
if __name__ == '__main__':
    foo()
 
def bar():
    print("hello")

Python 从第 1 行一直解析到第 4 行的入口,进而往回跳,调用到第 1 行的 foo() 函数,而其中的 bar() 函数还未及被解析到,所以会提示

NameError: name 'bar' is not define

如果把程序入口往后调

def foo():
    bar()
 
def bar():
    print("hello")
 
if __name__ == '__main__':
    foo()

上面代码执行无误,输出

hello

foo() 调用的 bar() 不也是在它下方声明的吗?所以这一点与 C 是有区别的。

这时候的理解是这样的,Python 从第 1 行自上往下解析到第 7 行的程序入口时,foo() 并未实际调用 bar(),但 foo() 和 bar() 函数都已解析到了,所以回过头来 foo() 与 bar() 之间怎么调用都无妨。

因此, 最好的实践方法就是把程序的入口放到代码的最下方,那么它前面的函数不管如何的声明顺序都没有关系 。 

### Python 代码执行顺序解析 #### 定义与基本概念 在Python中,程序默认按照自顶向下的方式逐行执行语句[^3]。这意味着每一行代码都会按其出现的先后次序被执行。 #### 主体代码与函数定义的区别 尽管整个文件中的指令遵循这种简单的线性流程来运行,但对于像`def`这样的关键字所引入的功能块——即函数定义,则不会立即触发内部逻辑的实际调用;相反,它们仅注册名称并等待后续通过显式的调用来激活相应的行为模式[^4]。 ```python # 这里只是声明了一个名为hanshu1的函数,并未真正执行其中的内容 def hanshu1(): print('我爱中华人民共和国!') print('函数的执行顺序!') # 同样地,这里也仅仅是创建了另一个函数对象 def hanshu2(): print('我爱代码!') # 当到达这一步时才会依次输出对应的字符串 hanshu2() print('好好工作,好好学习!') hanshu1() # 输出结果如下所示: # 我爱代码! # 好好工作,好好学习! # 我爱中华人民共和国! # 函数的执行顺序! ``` #### `if __name__ == "__main__":` 结构的作用 为了更好地组织大型项目以及区分模块作为脚本独立运行还是被其他地方导入的情况,在很多情况下可以看到存在一个特殊的条件判断: ```python if __name__ == '__main__': main_function_call_here() ``` 这段代码确保当该文件作为一个单独的应用启动时才去执行特定的操作(通常是入口点),而在它仅仅作为一种库资源供他人引用时不发生任何副作用[^1]。 #### 并发环境的影响 值得注意的是,虽然常规单线程环境下Python确实保持严格的顺序处理机制,但在涉及到多任务调度场景下(例如使用Threading或Multiprocessing包实现并发操作),不同部分之间可能会交错甚至乱序完成各自的任务,因此实际观察到的结果可能不再严格符合最初的书位置关系[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值