Python 函数为什么会默认返回 None?
Python 有一项默认的做法,很多编程语言都没有——它的所有函数都会有一个返回值,不管你有没有写 return 语句。
本文出自“Python为什么”系列,在正式开始之前,我们就用之前讨论过的 pass语句 和 ...对象 作为例子,看看 Python 的函数是怎样“无中生有”的:

可以看出,我们定义的两个函数都没有写任何的 return 语句,但是在函数调用后,都能取到一个返回值。
它们的执行效果跟直接写 return 语句相比,是完全相同的:

这 4 个例子属于两种类型:一种没有写 return,但是都有隐藏的 return 返回值;一种写了 return,而且实际也有返回值。
也就是说,后者在语义和行为上表现一致,前者虽然在语义上缺失,但是却有实际的行为和结果;后者的行为是显性的,前者却是隐性的。
《Python之禅》中有一句“显性胜于隐性(Explicit is better than implicit)”,但是,出于简洁和便利的考虑(Simple is better than complex),实际上 Python 中有很多行为都是隐性的,会把一些在语法层面的事交给解释器去完成。
上一期的 真值判断 是隐性的行为,本文前两个例子也是如此。
使用dis 查看字节码,就可以看到其背后的小动作:

在这个对比图中,可以看出上述 4 个函数的解释器指令一模一样!
不管有没有写 return,它们都会执行 return 的逻辑,而且默认的返回值就是 None。
那么,问题来了:Python 的函数为什么能默认返回 None 呢?它是如何实现的呢?
答案就在解释器中,当 CPython 解释器执行到函数的最后一个代码块时,若发现没有返回值,它就会主动地加上一个 Py_None 值返回(出自:compile.c):

也就是说,如果定义的函数没有返回值,Python 解释器就会(强行地)默认给我们注入一段返回逻辑!
对于解释器的这种附赠的服务,大家是觉得很贴心,还是嫌弃它多事呢?
这样的做法似乎没多少好处,但似乎也没有坏处?
那么,这就会引出新的问题:Python 为什么要求函数都要有返回值呢?为什么它不像某些语言那样,提供一个 void 关键字,支持定义无返回值的空函数呢?
关于这个问题,我们将在下一期“Python为什么”系列文章中揭晓。
如果你觉得这些问题很有启发性,那你应该会喜欢这些文章:
4、Python 为什么没有 main 函数?为什么我不推荐写 main 函数?
6、Python 为什么不支持 i++ 自增语法,不提供 ++ 操作符?
7、Python 为什么只需一条语句“a,b=b,a”,就能直接交换两个变量?
本文属于“Python为什么”系列(Python猫出品),该系列主要关注 Python 的语法、设计和发展等话题,以一个个“为什么”式的问题为切入点,试着展现 Python 的迷人魅力。所有文章将会归档在 Github 上,项目地址:https://github.com/chinesehuazhou/python-whydo
Python 函数为什么会默认返回 None?的更多相关文章
- python定义函数时的默认返回值
python定义函数时,一般都会有指定返回值,如果没有显式指定返回值,那么python就会默认返回值为None, 即隐式返回语句: return None 执行如下代码 def now(): prin ...
- 初识python 函数(定义,传参,返回值)
python基础(二): 菜鸟教程基础知识讲解的非常全面,内容选择我认为的重点输出一遍 函数: 定义一个函数: 你可以定义一个由自己想要功能的函数,以下是简单的规则: def fun(arg): pa ...
- python函数入参和返回值
以下内容参考自runoob网站,以总结python函数知识点,巩固基础知识,特此鸣谢! 原文地址:http://www.runoob.com/python3/python3-function.html ...
- python函数传入参数(默认参数、可变长度参数、关键字参数)
1.python中默认缺省参数----定义默认参数要牢记一点:默认参数必须指向不变对象! 1 def foo(a,b=1): 2 print a,b 3 4 foo(2) #2 1 5 foo(3,1 ...
- [python 函数学习篇]默认参数
python函数: 默认参数: retries= 这种形式 def ask_ok(prompt, retries=, complaint='Yes or no, please!'): while Tr ...
- python函数传参和返回值注意事项
函数传参 空参数 定义函数时括号里面没有形参,调用时不用传参. def func(): print('null para.') # 调用 func() 位置传参 规定形参的数量,调用时必须传递相同数量 ...
- python函数的使用和返回值
#coding=utf-8 def a(): i=1a() #函数的返回值,用return语句实现 #一个返回值的情况def test(): i=7 return iprint test() #多个返 ...
- Python 函数返回值
本章详细介绍 返回值: 0x 00 返回值简介 0x 01 指定返回值与隐含返回值 0x 02 return 语句位置与多条 return 语句 0x 03 返回值类型 0x 04 函数嵌套 0x 0 ...
- 9 - Python函数定义-位置参数-返回值
目录 1 函数介绍 1.1 为什么要使用函数 1.2 Python中的函数 2 函数的基本使用 3 函数的参数 3.1 参数的默认值 3.2 可变参数 3.2.1 可变位置传参 3.2.2 可变关键字 ...
随机推荐
- Java中解决继承和接口默认方法冲突
1)超类优先.如果超类提供了一个具体方法,同名而且有相同参数类型发默认方法会被忽略. 2)接口冲突.如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否是默认参数)相同的方 ...
- 在Spring Bean的生命周期中各方法的执行顺序
Spring 容器中的 Bean 是有生命周期的,Spring 允许在 Bean 在初始化完成后以及 Bean 销毁前执行特定的操作,常用的设定方式有以下十种: 通过实现 InitializingBe ...
- windy数(数位dp)
https://www.luogu.com.cn/blog/virus2017/shuweidp https://www.luogu.com.cn/problem/P2657 #include < ...
- OFD呼之欲来、来之跚跚,谁之罪?
软件国产化的浪潮势不可挡,美国逼得逾甚,我们压迫感逾强,唯有奋起直追方慰平生之志. 在板式文档领域,pdf已成为国际标准,亦可称为美国标准:它在该领域一枝独秀,已形成一览众山小之势! pdf出道20余 ...
- MacOS下JDK8的安装与配置
微信搜索"艺术行者",关注并回复关键词"jdk8"获取安装包和API文档资料! 一.安装环节 1.打开网页 https://www.oracle.com/jav ...
- HTML 布局 - 使用<div> 元素
网站布局 大多数网站会把内容安排到多个列中(就像杂志或报纸那样).高佣联盟 www.cgewang.com 大多数网站可以使用 <div> 或者 <table> 元素来创建多列 ...
- PHP preg_last_error() 函数
preg_last_error 函数用于返回最后一个 PCRE 正则执行产生的错误代码.高佣联盟 www.cgewang.com 语法 int preg_last_error ( void ) 实例 ...
- PHP zip_entry_compressionmethod() 函数
定义和用法 The zip_entry_compressionmethod() 函数返回 zip 档案项目的压缩方法.高佣联盟 www.cgewang.com 语法 zip_entry_compres ...
- PHP crc32() 函数
实例 输出 crc32() 的结果:高佣联盟 www.cgewang.com <?php $str = crc32("Hello World!"); printf(" ...
- C/C++编程笔记:C语言入门知识点(三),请收藏C语言最全笔记!
今天我们继续来学习C语言的入门知识点,第一课:C/C++编程笔记:C语言入门知识点(二),请收藏C语言最全笔记! 21. 输入 & 输出 当我们提到输入时,这意味着要向程序填充一些数据.输入可 ...