学径 LearnPath

编程语言基础

模块

将程序封装成工具集。

讲解模式

通过本节课,你将理解:

#goal

平方根、圆周率、随机整数——这些计算早就有人写好、检验过、收成可调用的形式。若每个程序都从四则运算重新推导,精力会耗在重复劳动上。

编程语言把一批相关的函数和常量收进一份可复用的工具,这份工具叫 模块。你声明要用哪一份,就可以调用里面已经完成的工作。这不是抄袭,而是科学的常态:站在他人已经完成的工作之上。

本节课你将学会 import,使用 math 与 random,并分清「整箱导入」与「只取出几件」的代价。

运行环境仍是本平台的 在线 IDE。

登月也没有从零发明算术

#hook

阿波罗导航计算机把飞行所依赖的计算收进有限的存储器与一套可调用的程序。没有人在指令舱里从加减乘除重新发明平方根。

工程的尊严不在于「全部自己写」,而在于清楚:哪些思想已经被封成可靠的层,哪些边界仍要由人来守。

阿波罗导航计算机主机与 DSKY
阿波罗导航计算机主机与 DSKY。Grabert / NASA。来源:Wikimedia Commons,公有领域。

AGC 是一套模块化系统的极端例子:显示与键盘是一层,导航方程是一层。宇航员按下的不是「从零算平方根」,而是已经检验过的例程。

本课的 import 远没有那么戏剧,原理相同:先声明你站在哪一层已经完成的工作上。

整箱搬入,点号取出

#explore-import

import math 是一句声明:此后可以使用 math 这个模块里已经被写好的名字。没有这句声明,math 对当前文件而言并不存在。

python
import math

print(math.pi)
print(math.sqrt(2))
print(math.sqrt(9))

点号左边是模块名,右边是名字。写 sqrt(9) 而不写 math.sqrt(9),Python 会认为当前文件里有一个叫 sqrt 的 函数——通常没有,于是报 NameError。

直角边为 3 和 4 时,斜边是:

python
print(math.sqrt(3 ** 2 + 4 ** 2))

应得 5.0。勾股定理你也许会证;平方根的数值算法你不必在本课重写。

只取出几件,来源会变淡

#explore-from

若确定只用平方根和圆周率,可以把它们拿到当前命名空间:

python
from math import sqrt, pi

print(sqrt(9), pi)

此后直接写 sqrt、pi。代价是:当前文件里不能再自己定义同名 sqrt;读代码的人也要记得这两个名字来自 math。

需要许多个名字、或希望一眼看出「这是数学库里的函数」时,整箱导入更清楚。不要把一箱子名字全部倒进来(from math import *):来源会变得不清楚,也容易互相踩踏。

随机是被规定的过程

#explore-random

科学里需要随机数,往往不是为了「随便」,而是为了抽样、模拟——并且仍能说明规则。

python
import random

print(random.randint(1, 6))
print(random.randint(1, 6))

random.randint(a, b) 返回 aa 到 bb 之间的整数,两端都包含。掷一枚六面骰子因此写 random.randint(1, 6)。

每次运行结果通常不同,这不是故障,而是这个模块的职责。若需要可重复的实验,可以在调用前设置种子:random.seed(0)。同一种子会得到同一串数。

本课只使用环境已提供的 math 与 random(海龟画图在后续课展开)。不必另行安装其他库。

本节练习:球体积与一次噪声

#practice

在 在线 IDE 里 import math,按 43πr3\dfrac{4}{3}\pi r^{3} 计算半径 r = 5 的球体积:(4 / 3) * math.pi * 5 ** 3,并打印。圆周率用 math.pi,不必另查数值。再 import random,打印一次 random.randint(0, 10)。用一行注释说明:结果是 0 到 10 的整数,两端都可能出现,再运行一次也不必相同。

本节要点

#review
  • 模块把可复用的思想变成可调用的工具。导入是声明:我将使用我并未写出的那一层。
  • 整箱导入后用点号取出;只取出几个名字时,来源会变淡。不要把一箱子名字全部倒进来。
  • 忘记导入或丢掉点号,会得到 NameError。名字不因你记得它就自动存在。
  • random.randint(a, b) 含两端。本课只使用在线 IDE 已提供的 math、random(以及后续课的 turtle)。

单选题

忘记点号

执行 import math 之后,哪一句能算出 9 的平方根?

单选题

randint 的闭区间

random.randint(1, 6) 可能取到哪些整数?

单选题

环境里有什么

在本平台在线 IDE 中,下面哪一项符合这门课的用法?

单选题

未导入的名字

尚未执行 import math,也没有 from math import sqrt,直接写 sqrt(9) 会怎样?

单选题

站在哪一层

使用模块时,更接近科学工作常态的态度是哪一项?

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