解决Python 函数声明先后顺序出现的问题


Posted in Python onSeptember 02, 2020

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

foo()

def foo():
 print("hello")

执行时会报出错误

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 中函数声明的顺序据我理解有两条规则

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

分析下面两段代码

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

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

NameError: name 'bar' is not define

有一个很好的分析工具 http://pythontutor.com/live.html#mode=edit,我们来看上面的代码

解决Python 函数声明先后顺序出现的问题

解释到第二行 bar() 的时候,Global frame 里只有 foo, bar 还不存在

如果把程序入口往后调

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

上面代码执行无误,输出

hello

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

也用http://pythontutor.com/live.html#mode=edit 来看看

解决Python 函数声明先后顺序出现的问题

解释到第 8 行的时候在 Global frame 中 foo, bar 都有了,所以能成功调用。

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

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

以上就是解决Python 函数声明先后顺序的问题的详细内容,更多关于python 函数声明顺序的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
使用Pyrex来扩展和加速Python程序的教程
Apr 13 Python
python中threading超线程用法实例分析
May 16 Python
Python处理Excel文件实例代码
Jun 20 Python
PyChar学习教程之自定义文件与代码模板详解
Jul 17 Python
把csv文件转化为数组及数组的切片方法
Jul 04 Python
Python使用jsonpath-rw模块处理Json对象操作示例
Jul 31 Python
python re正则匹配网页中图片url地址的方法
Dec 20 Python
python实现的自动发送消息功能详解
Aug 15 Python
对python中 math模块下 atan 和 atan2的区别详解
Jan 17 Python
Python数据可视化常用4大绘图库原理详解
Oct 23 Python
Pycharm如何自动生成头文件注释
Nov 14 Python
利用Python实现学生信息管理系统的完整实例
Dec 30 Python
解决Python3.8运行tornado项目报NotImplementedError错误
Sep 02 #Python
详解python with 上下文管理器
Sep 02 #Python
Python 的 __str__ 和 __repr__ 方法对比
Sep 02 #Python
Python datetime 如何处理时区信息
Sep 02 #Python
浅析python中的del用法
Sep 02 #Python
浅析NumPy 切片和索引
Sep 02 #Python
详解Python 函数参数的拆解
Sep 02 #Python
You might like
PHP多进程编程实例
2014/10/15 PHP
关于php中的json_encode()和json_decode()函数的一些说明
2016/11/20 PHP
PHP微信模板消息操作示例
2017/06/29 PHP
php模拟post提交请求调用接口示例解析
2020/08/07 PHP
dess中一个简单的多路委托的实现
2010/07/20 Javascript
jQuery1.5.1 animate方法源码阅读
2011/04/05 Javascript
jQuery中slideUp()方法用法分析
2014/12/24 Javascript
JS实现简单的键盘打字的效果
2015/04/24 Javascript
10条建议帮助你创建更好的jQuery插件
2015/05/18 Javascript
JS自定义选项卡函数及用法实例分析
2015/09/02 Javascript
javascript下拉列表中显示树形菜单的实现方法
2015/11/17 Javascript
jQuery动态加载css文件实现方法
2016/06/15 Javascript
jQuery基本选择器之标签名选择器
2016/09/03 Javascript
jQuery给指定的table动态添加删除行的操作方法
2016/10/12 Javascript
js实现定时进度条完成后切换图片
2017/01/04 Javascript
基于bootstrap实现bootstrap中文网巨幕效果
2017/05/02 Javascript
利用types增强vscode中js代码提示功能详解
2017/07/07 Javascript
基于JavaScript实现带数据验证和复选框的表单提交
2017/08/23 Javascript
解决在vue项目中,发版之后,背景图片报错,路径不对的问题
2018/03/06 Javascript
微信sdk实现禁止微信分享(使用原生php实现)
2019/11/15 Javascript
vue-video-player 解决微信自动全屏播放问题(横竖屏导致样式错乱问题)
2020/02/25 Javascript
npm ci命令的基本使用方法
2020/09/20 Javascript
[56:41]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 Newbee vs OG
2018/04/01 DOTA
Python Web框架Flask信号机制(signals)介绍
2015/01/01 Python
Django中几种重定向方法
2015/04/28 Python
使用python实现语音文件的特征提取方法
2019/01/09 Python
如何在scrapy中集成selenium爬取网页的方法
2020/11/18 Python
台湾百利市购物中心:e-Payless
2017/08/16 全球购物
将"引用"作为函数参数有哪些特点
2013/04/05 面试题
《棉鞋里的阳光》教学反思
2014/04/24 职场文书
党员干部廉洁自律承诺书
2015/04/28 职场文书
迎国庆主题班会
2015/08/17 职场文书
优秀党员主要事迹范文
2015/11/05 职场文书
创业计划书之书店
2019/09/10 职场文书
基于CSS3画一个iPhone
2021/04/21 HTML / CSS
SQL使用复合索引实现数据库查询的优化
2022/05/25 SQL Server