刚开始学 Python,很多人第一次写:
代码能运行,就觉得自己会 import 了。
但等项目稍微复杂一点,就会遇到各种问题:模块是什么?包又是什么?为什么有时候写import xxx,有时候又写from xxx import xxx?
其实把这几个概念理顺,Python项目结构会一下清晰很多。
一、模块是什么?
最简单的理解:
一个.py文件,就可以看成一个Python模块。
比如项目里有两个文件:
my_project/├── main.py└── calculator.py
在 calculator.py 中写一个函数:
def add(a, b): return a + b
那么 calculator.py 就是一个模块。
想在 main.py 里使用它,可以这样:
import calculator result = calculator.add(10, 20)print(result)
输出:
所以模块的意义很好理解:把不同功能拆到不同文件里,需要的时候再导入。
这样就不用把几百上千行代码全部塞进一个 main.py。
二、那“包”又是什么?
当项目越来越大,只有几个 .py 文件也会变得混乱。
这时候就可以继续把相关模块整理到一个目录中。
例如:
my_project/├── main.py└── utils/ ├── __init__.py ├── calculator.py └── formatter.py
这里的 calculator.py、formatter.py 是模块,而 utils 可以作为一个包来组织这些模块。
你可以简单记:
模块 =.py文件包 = 用来组织多个模块的目录结构
需要补充一点:现代Python支持没有 init.py 的“命名空间包”,所以不能绝对地说“没有 init.py 就不是包”。不过对于刚学习项目结构的新手,主动保留它通常更直观。
三、import到底有几种常见写法?
第一种:
import math print(math.sqrt(16))
这种方式导入整个模块,使用功能时需要写 math.sqrt()。
优点是来源非常清楚,代码一看就知道 sqrt 来自 math。
第二种:
from math import sqrt print(sqrt(16))
只导入需要的内容,后面可以直接使用 sqrt(),代码更简洁。
还可以给模块起别名:
import pandas as pdimport numpy as np
所以你经常会看到:
pd并不是另一个库,只是 pandas 的别名。
四、为什么不建议随便使用 import *?
有些教程里会出现:
看起来很方便,因为很多名字可以直接使用。
但我不建议新手养成这个习惯。
如果多个模块中存在相同名称的函数或变量,很容易出现命名冲突;代码一长,你也很难一眼判断某个函数究竟来自哪里。
所以相比:
更推荐:
或者:
明确导入自己真正需要的内容,代码通常更容易维护。
五、明明有这个文件,为什么import还是失败?
例如:
ModuleNotFoundError: No module named 'xxx'
先别急着反复 pip install。
因为你导入的可能根本不是第三方库,而是自己项目里的模块。
这时候可以先检查:文件名有没有写错、项目目录是否合理、当前运行位置是否正确、编辑器使用的Python解释器是否正确。
尤其是我们前面讲过虚拟环境之后,要记住:
“安装了”不等于“当前这个Python环境能找到”。
写在最后
模块和包听起来像两个专业概念,其实理解起来并不复杂:
模块负责拆分代码,包负责组织模块,import负责把需要的代码引进来。
当你开始写真正的Python项目,就不要再把所有代码都堆进一个文件。
试着把计算、文件处理、数据处理等功能拆成不同模块,再通过包进行整理。
慢慢你会发现:学会import不只是会写一条导入语句,而是在开始理解一个Python项目到底应该怎么组织。