在某些编程语言中,例如 C/C++、C#、PHP、Java、JavaScript 等等,do-while 是一种基本的循环结构。

它的核心语义是:先执行一遍循环体代码,然后执行一遍条件语句,若条件语句判断为真,则继续执行循环体代码,并再次执行条件语句;直到条件语句判断为假,则跳出循环结构。

流程图如下(Java 示例):

// 打印小于 20 的数字
public class Test {public static void main(String[] args){int x = 10;do {System.out.print("value of x : " + x );x++;System.out.print("\n");} while(x < 20);}
}

Python 并不支持 do-while 结构,“do”并不是一个有效的关键字。

那么,为什么 Python 不提供这种语法结构呢,这种现状的背后有何种设计考量因素呢?

在回答这个问题之前,让我们再仔细思考一下 do-while 语法可以解决什么问题,看看使用这种结构能带来什么好处?

最显而易见的好处是:do-while 语法保证了会先执行一遍循环体代码。

它的使用场景也许不多,但是,跟普通的 while 循环或者 for 循环语法的“条件前置”思想不同,它体现的是一种“条件后置”的编程逻辑,也是一种控制循环的常见方式。

它们的关系似乎有点像 C/C++ 这些语言中的i++++i操作的区别,在某些特殊场合中,也许会更为高效。

除了这一特点,这种结构最大的应用场景其实是在 C/C++ 中特殊的do {...} while (0) 用法。这在很多开源项目的源码中都能找到踪迹,例如 Linux、Redis 以及 CPython 解释器,等等。

这里面的数字 0 表示布尔值 False,意味着循环只会执行一遍,然后就跳出。

这样的写法是不是很诡异?所谓“循环”,一般就意味着程序体会被反复执行多次,但是,do {...} while (0) 却偏偏只需要它执行一遍,这初看起来是有点多余啊。

这种写法主要用在宏函数的定义中,可以解决宏代码块的编译问题,使代码按照我们的意图而合理分块。

另外,do {...} while (0) 结合 break 使用,还可以实现很优雅的跳转控制效果。

在下面的示例中,步骤 1、4 和 5 要求必须执行,而步骤 2 取决于步骤 1 的执行结果,步骤 3 则取决于步骤 2 的执行结果。

do {// 执行步骤 1 if (条件1失败) {break;}// 执行步骤 2 if (条件2失败) {break;}// 执行步骤 3 if (条件3失败) {break;}
} while(0);
// 执行步骤 4
// 执行步骤 5

在这种场景中,我们确实只需要按照顺序执行一遍。do-while 结构很清晰,避免造成多层条件嵌套或者设置诸多额外标记的局面。

最后还有一点,在汇编层面,do-while 比 while 更接近汇编语言的逻辑,可以节省使用指令,在过去的低内存时代,算得上是一种优化写法。

分析完 do-while 的好处后,让我们回到主题:Python 为什么不需要设计 do-while 循环语法呢?

首先,Python 离底层应用编程太远了,就不用考虑汇编指令的优化了,同时,它也不涉及宏的使用。

至于“条件前置”和“条件后置”的区别,其实并没有太大影响,而且,由于 Python 使用简洁优雅的缩进加冒号语法来划分代码块,导致直译过来的 do-while 语法看起来会很怪异(注意,直译的 while 的条件后没有其它内容):

do:pass
while False

想要引入新的语法特性,必然要遵守既定的风格习惯。其它语言的 do-while 结构直译成 Python 的话,肯定不合适。

事实上,在 2003 年时,有一个 PEP 提议给 Python 加上 do-while 语法支持:

PEP-315 Enhanced While Loop

该 PEP 提议增加一个可选的 do 子句,支持将 while 循环扩展成这样子:

do:<setup code>
while <condition>:<loop body>

这不是简单地从其它语言翻译成 Python,它的 while 语句后保留了 Python 的缩进用法,并不会造成直译形式的突兀结果。

加上 while 循环本身已支持的可选的 else 子句,因此,while 完整的语法结构是这样的:

while_stmt : ["do" ":" suite]"while" expression ":" suite["else" ":" suite]

(PS.在本系列的下一篇文章,我们将解释为什么 Python 要支持 while-else 语法)

也就是说,在保持原 while 循环语法不变的情况下,PEP-315 提议支持在 while 前面使用一个可选的 do 子句。

do 子句只会执行一遍,当它里面出现 break 时,则跳出整个 do-while 循环;当 do 子句中出现 continue 时,则跳出 do 子句,进到 while 的条件判断中。

有了 do 子句后,很容易就能实现 do {...} while (0) 的跳转控制效果。

但是,这个 PEP 遭到了一些核心开发者的反对。

反对的理由是,不需要引入新的关键字和语法,仅使用现有语法就能很好地实现同样的功能:

while True:<setup code>if not <condition>:break<loop body>

Python 之父 Guido van Rossum 也持反对意见,他的原话是:

Guido的回复

Please reject the PEP. More variations along these lines won't make the language more elegant or easier to learn. They'd just save a few hasty folks some typing while making others who have to read/maintain their code wonder what it means.

简单翻译一下,这种 do-while 语法并不会使 Python 更优雅好用,反而会产生阅读/维护代码的理解负担。

就个人的感觉而言,我也不赞成引入 PEP-315 那种可选的 do-while 语法,虽然它比固定形式的 do-while 结构更为灵活和优雅一点。

最后稍微总结一下,do-while 作为一种常见的循环结构,在其它语言中有所发挥,它甚至还发展出了do {...} while (0) 的典型用法,但是,do-while 能够解决的几个问题要么在 Python 中并不存在(宏定义、汇编指令),要么就是已经有更为合适而低成本的实现(跳转控制)。

看完这篇文章,你是否还有其它补充的内容呢?欢迎交流讨论。

这是我开发的机器人公众号小号,目前增加了天气查询,955公司名单,关注时间查询;后面还会增加图片功能和每日送书抽奖送书活动,以及调戏功能,欢迎来体验,捧场。

一个机器人公众号已经上线,欢迎调戏

推荐阅读:
入门: 最全的零基础学Python的问题  | 零基础学了8个月的Python  | 实战项目 |学Python就是这条捷径
干货:爬取豆瓣短评,电影《后来的我们》 | 38年NBA最佳球员分析 |   从万众期待到口碑扑街!唐探3令人失望  | 笑看新倚天屠龙记 | 灯谜答题王 |用Python做个海量小姐姐素描图 |碟中谍这么火,我用机器学习做个迷你推荐系统电影
趣味:弹球游戏  | 九宫格  | 漂亮的花 | 两百行Python《天天酷跑》游戏!
AI: 会做诗的机器人 | 给图片上色 | 预测收入 | 碟中谍这么火,我用机器学习做个迷你推荐系统电影
小工具: Pdf转Word,轻松搞定表格和水印! | 一键把html网页保存为pdf!|  再见PDF提取收费! | 用90行代码打造最强PDF转换器,word、PPT、excel、markdown、html一键转换 | 制作一款钉钉低价机票提示器! |60行代码做了一个语音壁纸切换器天天看小姐姐!|

年度爆款文案

  • 1).卧槽!Pdf转Word用Python轻松搞定!

  • 2).学Python真香!我用100行代码做了个网站,帮人PS旅行图片,赚个鸡腿吃

  • 3).首播过亿,火爆全网,我分析了《乘风破浪的姐姐》,发现了这些秘密

  • 4).80行代码!用Python做一个哆来A梦分身

  • 5).你必须掌握的20个python代码,短小精悍,用处无穷

  • 6).30个Python奇淫技巧集

  • 7).我总结的80页《菜鸟学Python精选干货.pdf》,都是干货

  • 8).再见Python!我要学Go了!2500字深度分析!

  • 9).发现一个舔狗福利!这个Python爬虫神器太爽了,自动下载妹子图片

点阅读原文,看B站我的视频!

Python 为什么不设计 do-while 循环结构?相关推荐

  1. Python程序控制结构(二)循环结构:for in遍历循环,while无限循环,循环+else

    Python程序控制结构(二)循环结构: 1. for in遍历循环 2. while无限循环 一.遍历循环 二.遍历循环的应用 遍历循环是使用for in保留字形成的一种循环,它能够对遍历结构中的每 ...

  2. python循环结构教学设计_Python程序设计 循环结构说课稿

    循环结构程序设计 -- 实现复杂计算程序 一.说教材 1. 教材地位分析 教材是由湖北省中小学教材编写组编写的义务教育教科书<信息技术> .其中<循 环结构程序设计>是初中信息 ...

  3. python最基本的两种循环结构_Python基础 — 分支和循环

    1. 分支结构 1.1 初步介绍 至今,我们所写的Python代码都是顺序执行,但是有时候在代码中是需要进行逻辑判断的,比如用户 输入用户名和密码,输入正确则验证通过,否则即验证失败.这个时候就会产生 ...

  4. python实现素数筛选法_从零开始学Python系列-第6讲:循环结构

    应用场景 我们在写程序的时候,一定会遇到需要重复执行某条或某些指令的场景.例如用程序控制机器人踢足球,如果机器人持球而且还没有进入射门范围,那么我们就要一直发出让机器人向球门方向移动的指令.在这个场景 ...

  5. python入门之控制结构-循环结构_(一)Python入门-4控制语句:05while循环结构-死循环处理...

    一:循环结构介绍 循环结构用来重复执行一条或多条语句.表达这样的逻辑:如果符合条件,则反 复执行循环体里的语句.在每次执行完后都会判断一次条件是否为 True,如果 为True则重复执行循环体里的语句 ...

  6. 洛谷刷题记录(python)【入门3】循环结构

    [入门3]循环结构https://www.luogu.com.cn/training/102#problemsP5718 [深基4.例2]找最小值 n = int(input()) a = [int( ...

  7. python遍历循环中的遍历结构可以是什么_(一)Python入门-4控制语句:06for循环结构-遍历各种可迭代对象-range对象...

    一:for循环和可迭代对象遍历 for 循环通常用于可迭代对象的遍历.for 循环的语法格式如下: for 变量 in 可迭代对象: 循环体语句 可迭代对象: Python包含以下几种可迭代对象: 1 ...

  8. 设计性实验-循环结构:搬砖问题。36块砖,36人搬;男搬4,女搬3,两个小孩抬一砖。要求一次全搬完,问男、女、小孩各需若干?

    #include<stdio.h> int main() {int x,y,z; //定义循环变量for (x=0; x<36; x++){for (y= 0; y<36; y ...

  9. Python基础------几种循环结构详解

    Python基础------几种循环结构详解 在所有的编程语言中,循环结构是必不可少了,Python也一样.在python主要有一下几种循环结构:for-in-.while.range()三种最为常见 ...

  10. 分支与循环结构测试题(有答案版)

    习题目录 python基础知识之分支与循环结构练习题 一.基础题: 分别用单分支结构和多分支结构实现判断一个年份是否是闰年. 写出判断⼀个数是否能够被2或者5整除,但是不能同时被2或者5整除的条件语句 ...

最新文章

  1. 云计算公司Zuora提交IPO申请 预计募资1亿美元
  2. ISME:胡锋/朱永官等揭示土壤噬菌体-宿主菌协同应对有机氯农药胁迫机制
  3. python自带的shell是什么-python shell是什么东西?
  4. [Google Guava] 使用和避免null
  5. 线程同步工具(七)在并发任务间交换数据
  6. 自我认为挺全面的【Web Service渗透测试总结】
  7. 「Innovation 2021」网易应用创新开发者大赛正式收官,十强选手精彩对决
  8. (七)python3 只需3小时带你轻松入门——List与dict
  9. 使用所有对象通用的方法
  10. 基于ROS的移动机器人开发:视觉、语音、导航
  11. SSM框架搭建过程----学生学籍管理系统
  12. Oracle外键级联删除和级联更新
  13. Saltstack 安装应用笔记一
  14. 动词ing基本用法_高中英语:非谓语动词 ( 附非谓语口诀)
  15. 计算机的神奇小游戏,电脑课我们常玩的13个小游戏
  16. Android Studio 全局搜索技巧
  17. 哪吒之魔童降世视听语言影评_《哪吒之魔童降世》观后感精彩影评5篇450字
  18. Java模拟醉汉行走问题_醉汉随机行走问题的统计学模型.pdf
  19. 阿里P9纯手打亿级高并发系统设计手册,走进阿里的架构世界
  20. Teamviewer检测为商业用途的解决方案

热门文章

  1. 【装机吧】原版XP系统安装教程(完整版)
  2. Skype 与 Skype for Business 之间有何区别?
  3. Apache POI 合并单元格
  4. oracle 一个实例创建多个数据库_创建多个Oracle数据库及相应的实例
  5. numpy报ValueError: could not broadcast input array from shape
  6. XP系统自带截屏功能操作方法
  7. 直线绘制算法-Bresenham算法
  8. 【阿里 | 飞猪 | 校招】客户端开发工程师 一面
  9. google成功经验总结分析
  10. RocketMQ压测报告书