# 知识库

# 2.3.3 模块与包的使用

模块是一个包含 Python 代码的文件；包是一个包含 `__init__.py` 文件的目录。编程时如需使用某个模块，首先要使用 `import` 语句将该模块导入。课程给出四种导入方式。

第一种，导入整个模块。格式为 `import 模块名`，使用格式为 `模块名.函数名`。例如 `import math` 后，`math.pi` 得到圆周率 `3.141592653589793`，`math.sin(math.pi / 2)` 得到 `1.0`。第二种，导入模块中的指定对象。格式为 `from 模块名 import 对象名列表`，导入后直接使用对象名、不加模块名。例如 `from math import cos, pi` 之后，`cos(pi/4)` 的结果是 `0.7071067811865476`。第三种，导入模块中的所有内容。格式为 `from 模块名 import *`，导入后可以使用模块中的所有对象，而不加模块名。例如 `from math import *` 之后，`sqrt(16.0)` 得到 `4.0`。这种方式容易与当前程序中的名字冲突，较大程序中一般不推荐。第四种，给导入的模块或对象起别名。格式为 `import 模块名 as 别名`，或 `from 模块名 import 对象名 as 别名`，使用简短的别名代替模块名。例如 `from random import randint as rand` 之后可用 `rand(10, 20)` 生成随机整数。数据科学中常见写法是 `import numpy as np`、`import pandas as pd`。

导入机制的本质是把名字放入当前程序的命名空间。`import math` 只引入模块名 `math`，因此必须写成 `math.pi`；`from math import pi` 则把 `pi` 直接放进当前命名空间，所以不能再写 `math.pi`。调用写法必须与导入方式一致。

`random` 模块是 Python 标准库中专门用于生成随机数和执行随机操作的模块。【例2-12】一次导入 `randint`、`random`、`uniform` 三个函数：`randint(20, 60)` 生成该闭区间上的随机整数；`random()` 生成随机浮点数；`uniform(3, 4)` 生成指定区间上的随机浮点数。循环打印时用 `end=' '` 可使多个结果出现在同一行。每次运行得到的随机值通常不同，不必死记某一次演示的数字。

常见坑：未导入就使用对象会引发 `NameError`；`import math` 后直接写 `pi` 而漏掉模块名前缀；已经 `from math import pi` 却再写 `math.pi`；`from ... import *` 覆盖同名对象；把本节约导入语法与下一节第三方库的安装混为一谈。选用导入方式时，优先导入整个模块或指定对象，需要时再起别名。

## 关键要点
- 模块：一个包含 Python 代码的文件；包：一个包含 `__init__.py` 文件的目录。
- 使用模块前必须先用 `import` 导入。
- 导入整个模块：`import 模块名`，使用 `模块名.函数名`。示例：`import math` 后 `math.pi`、`math.sin(math.pi / 2)`。
- 导入指定对象：`from 模块名 import 对象名列表`，直接使用对象名。示例：`from math import cos, pi` 后 `cos(pi/4)`。
- 导入全部内容：`from 模块名 import *`，直接使用全部对象。示例：`from math import *` 后 `sqrt(16.0)`。
- 起别名：`import 模块名 as 别名` 或 `from 模块名 import 对象名 as 别名`。示例：`from random import randint as rand`；`import numpy as np`；`import pandas as pd`。
- `random` 是标准库模块；【例2-12】常用 `randint`、`random`、`uniform`。
- 常见坑：漏导入、导入方式与调用写法不一致、`import *` 造成名字冲突。

---
