学径 LearnPath

编程语言基础 / Wiki

代码嵌套

一块语句写进另一块里;缩进每深一层,从属就深一层。

它是什么

代码嵌套 是把一段程序写进另一段程序的内部。一支 选择 里面再写一支选择,循环里面再写选择,都是这种结构。外层决定能不能走进去;走进去之后,内层才开始自己的判断。外层不成立,内层那一问根本不会被提出。

缩进 标明从属。往右移一层,表示「我在里面」;移回与外层对齐,表示内层已经结束。层次是模型的一部分,不是排版。

python
a = 0
b = 1
if a == 0:
    if b == 0:
        print("有无数解")
    else:
        print("无解")
else:
    print(-b / a)

解 ax+b=0ax+b=0 时,先问 aa 是不是 00。只有 aa 为 00,才继续问 bb:两个都是 00,方程有无数解;aa 为 00 而 bb 不是,则无解。aa 不是 00 时,内层整块被跳过,直接计算 −b/a-b/a。

名字从哪来

nesting 的本义是筑巢,也指一层套一层。结构化程序把顺序、选择、循环当成可以互相放入的构件:一块的内部仍然可以是完整的一块。1966 年,科拉多·博姆(Corrado Böhm)与朱塞佩·亚科皮尼(Giuseppe Jacopini)证明,这三种结构足以表达可计算的流程。嵌套就是把它们叠起来,而不是另造一种新的控制方式。

它怎么工作

解释器先处理外层。外层条件为假,整块内层被跳过,包括内层自己的 else。外层为真,才进入内层,再按内层的条件选择。上面的例子里,aa 不是 00 时,打印「无解」的那一支不会执行——它属于内层,不属于「aa 不是 00」。

else 配的是同一层、离它最近的那个 if,不是页面上方随便一个 if。缩进若对不齐,配对就会跟眼睛看到的不一样。见 缩进。

嵌套一深,人就容易跟丢每一层在保护什么,见 缩进地狱。能改写成同一层上的 elif,或把内层收成 函数,往往更清楚。那是可读性上的选择,不是嵌套在语法上不合法。条件若只是「并且」「或者」,有时不必再套一层代码,见 逻辑嵌套。

生活里在哪里

安检先看有没有票,有票才看行李是否合规。没有票,行李那一项不会被问到。医院分诊先看是不是急症,是急症才进入下一步分流;不是急症,后面的细分并不因此自动生效。分类讨论也是同一件事:先分大类,再在大类里面分小类。外层分错了,内层写得再细也走不到。

和相近概念的差别

代码嵌套是块套块,缩进变深。逻辑嵌套 是条件套条件,合成之后仍然是一个路口,不必多出一层缩进。elif 是同一层上的互斥兄弟,不是把一支写进另一支里面。连续几个独立的 if 则可能不止走一支。

递归 是函数调用自己,去处理更小的同类问题。调用在变深,但那不是把 if 的子块再缩进一层。循环内部再写选择,是嵌套;循环自己重复的是同一层步骤,见 循环。

常见误会

误会 1:else 会配最外层的 if。

它配同一层里最近的那个 if。缩进退回哪一层,就在哪一层配对。

误会 2:外层为假时,内层的 else 仍会执行。

不会。外层不成立,内层整块被跳过,里面的 if 和 else 都不会运行。

误会 3:嵌套和一串 elif 是一回事。

elif 是平级的互斥分类:前一条失败,才检查下一条。嵌套是外层成立之后才出现的下一问。两种写法覆盖的情形不同。

想知道更多

  • 书:布鲁克希尔《计算机科学概论》
  • 书:艾伦·唐尼《像计算机科学家一样思考Python(第2版)》
  • 书:埃里克·马瑟斯《Python编程:从入门到实践(第3版)》

未登录时不会保存学习进度