void 是编程语言中最常见的关键字之一,从字面上理解,它是“空的、空集、空白”的意思,最常用于表示函数的一种返回值类型。

维基百科上有一个定义:

The void type, in several programming languages derived from C and Algol68, is the type for the result of a function that returns normally, but does not provide a result value to its caller.
在 C、Algol68 及它们所派生的几种编程语言中,void 类型是函数正常返回的一种类型,但是不会给调用者返回一个值。

简单来说,void 是一种类型(type),但是没有具体的值(value)。

这到底是什么意思呢?

以 Python 的几种常见类型为例,我们可以从对比中看出规律:int 是一种表示整数的类型,它有无限个可能的整数值;bool 是一种布尔类型,它有两个可能的值(True 和 False);NoneType 是一种表示 None 的类型,它只有一个值(None)。

至于 void,它是一种更为抽象的特殊类型,但是不包含任何值。

介绍完概念上的含义,我们就可以进入正题了。标题中的问题可以进一步分解成两个:

  • 其它语言为什么要使用 void 关键字?
  • Python 为什么不设计出 void 关键字?

对于第一个问题,我们以 C/C++ 为例,先看看 void 的两种使用场景(PS:此处只考虑函数的用法,不考虑指针的用法,因为 Python 没有指针):

当 void 用在函数的参数位置时,它表示该函数不需要传参。

最初 C 语言的f() 表示参数数量不确定,为了另外表达“不需要参数”的语义,所以引入f(void) 作为限定。后来的语言(包括 Python)基本不在参数中使用 void,而是直接用f() 表示不需传参。C++ 为了兼容 C,所以才同时支持这两种语法。

当 void 用在函数前作修饰时,它表示该函数没有返回值。

在 C 语言中,若不声明返回类型,则f() 函数在编译后会返回整型的值。为了避免混乱,当不需要返回值时,就使用void f() 来作限定。

同时,更主要的是,它还起到了占位符的作用,表明一个函数的类型是已知的,这对代码可读性和编译都有所帮助。

void 作为函数的空返回值类型,这种用法在 C++/Java 中也被继承了。另外,在 Javascript 中也有 void 的身影,只不过它成了一种操作符,起到了完全不同的作用,此处不表。

但是,Python 从头到尾都没有 void 关键字。

为什么会这样?难道是因为在 Python 中不存在其它语言所面对的问题么?还是说,Python 中有自己的一套解决方案?

仍以跟函数相关的两种用法为例作分析吧。

在表示函数不需传参时,f(void)这种写法根本就是多余的,所以 Python 使用了最简单明了的无参式写法f()

至于返回值类型的用法,在我们定义出一个函数时,例如最简单的def func():pass ,为了让它的调用结果func() 是一个合法的对象,那它必须具有一个有效的类型(type)。

这应该是以类型为基的编程语言都会遇到的共性问题,Python 也不例外。

这个时候,如果函数本身没有显式地 return 出一个对象的话,就有两种可能的解决办法:

  • 方法一,即声明该函数为 void 类型,像 C 和其它语言所做的那样,只要能通过类型检查即可
  • 方法二,则是 Python 所用的方法,即令解释器隐式地返回一个 None 对象,也就是令函数默认得到一个 NoneType 类型,再用于类型检查(PS:Javascript 也类似,只不过它默认返回的是 undefined,它不是一个对象,而是一种表示“未定义”的类型,类似于 void)

简单而言,Python 的设计思路是直接复用已有的 NoneType 类型,并让解释器来填补缺失掉的函数类型。

关于 Python 解释器的这个隐式填补过程,我已在上一篇《Python 函数为什么会默认返回 None?》文章详细分析过,感兴趣的同学可去查阅。

这样做的好处至少有两点:一是没有引入新的 void 类型和关键字;二是不需要程序员在函数前声明返回类型,这就跟有显式返回值的写法保持了一致。

试想一下,如果 Python 不让函数默认有返回值的话,就可能要写成 void def func():... 这样的形式,那它就变成了函数定义时的一种特例。与另一种特例函数相比,即异步函数asyc def func():... ,就可能引起混乱。

总体而言,Python 似乎认为 void 空类型不是那么有存在的必要,似乎 NoneType 类型就足够了,而当缺少返回值时,让解释器统一注入是极为方便的,因此才出现了我们看到的现状。

至此,文章标题的问题算是圆满回答了。

最后,让我们开始进入 ending 吧:本文明面上是以“Python 为什么没有 void 关键字”为切入点,然而,它实际上瞄准的却是“Python 为什么需要返回 None”的问题。

在《Python 函数为什么会默认返回 None?》这篇文章中,我介绍了 Python 中函数默认返回 None 的机制,它是属于“how can”的内容。但是为什么要默认返回 None 呢?这则是属于“why need”或者“why should”的问题,而它需要从 void 关键字的缺失开始谈起……

那么,为什么 Python 没有 void 关键字呢?请往上翻,重新阅读本文……

本文属于“Python为什么”系列(Python猫出品),该系列主要关注 Python 的语法、设计和发展等话题,以一个个“为什么”式的问题为切入点,试着展现 Python 的迷人魅力。所有文章将会归档在 Github 上,项目地址:https://github.com/chinesehuazhou/python-whydo

python return用法_Python 为什么没有 void 关键字?相关推荐

  1. python return怎么用,python return用法是什么

    python return用法:1.返回函数的返回值:2.终止程序的运行,提前退出,例如,当函数内有错误发生时,使用return可以终止函数的运行. 本教程操作环境:windows7系统.python ...

  2. python表示空类型的关键字_Python 为什么没有 void 关键字?

    原标题:Python 为什么没有 void 关键字? void 是编程语言中最常见的关键字之一,从字面上理解,它是"空的.空集.空白"的意思,最常用于表示函数的一种返回值类型. 维 ...

  3. python基本用法_Python基本用法总结

    Python 的设计具有很强的可读性,易于使用.这里对python基本用法做一个总结介绍. 一. 变量类型 1. 变量赋值 Python中的变量赋值不需要类型声明,每个变量在使用前都必须赋值,变量赋值 ...

  4. python end用法_python中end的使用方法

    python中end的使用方法 发布时间:2020-06-17 09:47:13 来源:亿速云 阅读:178 这篇文章给大家分享的是有关python中end的使用方法,小编觉得挺实用的,因此分享给大家 ...

  5. python try用法_python中的try的用法

    展开全部 try语句32313133353236313431303231363533e78988e69d8331333431366238是python里面的控制语句,与except,finally配合 ...

  6. python elseif用法_Python关键字简介

    本文旨在提供对Python关键字的详细了解. 1. True:此关键字用于表示布尔值true.如果条件为真,则打印"True". 2. False:此关键字用于表示布尔值false ...

  7. python返回值return用法_Python中return函数返回值代码实例用法

    本篇文章小编给大家分享一下Python中return函数返回值代码实例用法,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. return 添加返回值 r ...

  8. python elif 用法_Python,为什么要使用elif关键字?

    我刚刚开始Python编程,而我想知道elif关键字. 我在使用else if之前使用的其他编程语言. 有谁知道为什么Python开发人员添加了额外的elif关键字? 为什么不: 1 2 3 4 5 ...

  9. python elseif用法_python学习笔记(一)

    0.前言 本文是根据廖雪峰python教程学习总结而来. 参考<python学习手册>,<流畅的python>以及python官方手册等网络资料 略过了与C和C++ 语言相同的 ...

最新文章

  1. OpenCV中的SURF(Speeded-Up Robust Features 加速鲁棒特征)
  2. android xposed 编译,Xposed修改特征编译
  3. 教程:使用Data Lake Analytics + OSS分析CSV格式的TPC-H数据集
  4. VC++源码分析 - 中国象棋源码分析
  5. ADVM/ACFS is not supported on centos-release-5-5.el5.centos 解决方法
  6. iOS开发笔记[16/50]:Views
  7. 数据平台、大数据平台、数据中台……傻傻分不清?这次终于有人讲明白了!
  8. bootstrapTable表格表头换行
  9. python通过内置函数测试对象类型_python测试开发(01-递归函数+内置函数)
  10. ListView 搜索函数
  11. 谈谈MySQL InnoDB存储引擎事务的ACID特性
  12. 2015 年 4 月份 LeanCloud 更新汇总
  13. unity下载官网地址
  14. Python题目:判断101-200之间有多少个素数,并输出所有素数,简单方法
  15. CAN总线学习:zlg关于can帖子汇总
  16. Visio 导出图片时字符间距错乱
  17. 企业开源办公虚拟专用网工具
  18. Java Web课程体系
  19. QXRService:基于高通QXRService获取SLAM Camera图像
  20. python使用matplotlib库构建动态图表 --基于animation模块

热门文章

  1. html 数据钩子,22.钩子函数.html
  2. oracle 磁盘不分区吗,LINUX停ORACLE软件、数据文件等所在的磁盘分区空间不足的解决思路...
  3. php运行资源库,如何在sublime上运行php
  4. mysql 数组判断_mysql 判断两个数组是否有交集
  5. php fsockopen socket,PHP利用socket(fsockopen)的简单示例
  6. 面向对象的三大特征之一:继承
  7. 计数排序Counting sort
  8. BZOJ 2045 容斥原理
  9. 【OpenStack】OpenStack系列9之Compute节点安装
  10. 深入了解一下PYTHON中关于SOCKETSERVER的模块-B