解决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 相关文章推荐
值得收藏,Python 开发中的高级技巧
Nov 23 Python
基于python实现KNN分类算法
Apr 23 Python
基于python二叉树的构造和打印例子
Aug 09 Python
使用python批量修改文件名的方法(视频合并时)
Mar 24 Python
10行Python代码计算汽车数量的实现方法
Oct 23 Python
Python字典常见操作实例小结【定义、添加、删除、遍历】
Oct 25 Python
Python3+selenium实现cookie免密登录的示例代码
Mar 18 Python
Python接口测试数据库封装实现原理
May 09 Python
解决keras GAN训练是loss不发生变化,accuracy一直为0.5的问题
Jul 02 Python
Python django框架 web端视频加密的实例详解
Nov 20 Python
Python爬虫进阶之爬取某视频并下载的实现
Dec 08 Python
python plt.plot bar 如何设置绘图尺寸大小
Jun 01 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中DIRECTORY_SEPARATOR,PATH_SEPARATOR两个常量的作用
2013/06/21 PHP
PHP内置过滤器FILTER使用实例
2014/06/25 PHP
php使用自带dom扩展进行元素匹配的原理解析
2020/05/29 PHP
js操作textarea方法集合封装(兼容IE,firefox)
2011/02/22 Javascript
js如何取消事件冒泡
2013/09/23 Javascript
JS小游戏之宇宙战机源码详解
2014/09/25 Javascript
jQuery实现根据类型自动显示和隐藏表单
2015/03/18 Javascript
Nodejs实战心得之eventproxy模块控制并发
2015/10/27 NodeJs
基于javascript实现精确到毫秒的倒计时限时抢购
2016/04/17 Javascript
webpack中引用jquery的简单实现
2016/06/08 Javascript
js时间查询插件使用详解
2017/04/07 Javascript
浅谈JS获取元素的N种方法及其动静态讨论
2017/08/25 Javascript
基于javascript 显式转换与隐式转换(详解)
2017/12/15 Javascript
vue用递归组件写树形控件的实例代码
2018/07/19 Javascript
jQuery实现数字自动增加或者减少的动画效果示例
2018/12/11 jQuery
产制造追溯系统之通过微信小程序实现移动端报表平台
2019/06/03 Javascript
vue router 传参获取不到的解决方式
2019/11/13 Javascript
JS常见错误(Error)及处理方案详解
2020/07/02 Javascript
js+h5 canvas实现图片验证码
2020/10/11 Javascript
Nest.js散列与加密实例详解
2021/02/24 Javascript
Python对小数进行除法运算的正确方法示例
2014/08/25 Python
Python+tkinter模拟“记住我”自动登录实例代码
2018/01/16 Python
python 读取竖线分隔符的文本方法
2018/12/20 Python
Python面向对象之类的封装操作示例
2019/06/08 Python
Python 分享10个PyCharm技巧
2019/07/13 Python
pytorch::Dataloader中的迭代器和生成器应用详解
2020/01/03 Python
Django中日期时间型字段进行年月日时分秒分组统计
2020/11/27 Python
HTML5-WebSocket实现聊天室示例
2016/12/15 HTML / CSS
html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因
2013/01/09 HTML / CSS
Betsey Johnson官网:妖娆可爱的连衣裙及鞋子、手袋和配件
2016/12/30 全球购物
英国最大的老式糖果店:A Quarter Of
2017/04/08 全球购物
师范教师毕业鉴定
2014/01/13 职场文书
请假条格式范文
2014/04/10 职场文书
个人四风问题对照检查材料
2014/09/26 职场文书
2015年助理政工师工作总结
2015/05/26 职场文书
2019年聘任书的写作格式及范文!
2019/07/03 职场文书