上一章我们已经把 import 最常见的几种写法理顺了。你已经知道:
一个 .py 文件通常就是一个模块import 的本质,是把别的模块里的内容拿过来用 模块拆分的意义,不只是为了能运行,更是为了让代码结构更清晰、更容易复用
那接下来,一个特别重要的认知就来了:
很多初学者一提到导入,脑子里想到的都是别人写好的库,比如 math、random、os。 但你很快就要意识到,不只是别人能写模块,你自己也能写模块。
而且不只是模块,你还可以把多个模块再组织成一个更大的结构,这就是包。
这一章我们就把这两件事讲清楚:
什么叫自定义模块 什么叫包 为什么你的代码也完全可以被别人导入和复用
这一步一旦迈过去,你的代码思维会明显从“写一个脚本”往“搭一个小项目”转。
一、什么叫自定义模块
先说最直接的定义:
你自己写的 .py 文件,只要里面放了可复用的代码,它就是自定义模块。
注意,这个定义一点都不复杂。
比如你新建一个文件:
my_math.py
里面写:
defadd(a, b):return a + bdefsub(a, b):return a - b
这个 my_math.py,就是你自己定义的一个模块。
为什么叫“自定义”?
因为它不是 Python 自带的,也不是第三方库下载来的,而是你自己写出来的。
这说明一个非常重要的事实:
模块不是高高在上的“库”,模块首先就是你自己能写出来的代码文件。
二、为什么说你的代码也可以被别人导入
因为导入这件事,本质上和“这个模块是谁写的”没关系。
Python 不在乎这个模块是不是官方写的。 它也不在乎是不是某个 유명库写的。 它只关心一件事:
你给出的模块里,有没有合法的 Python 代码,以及当前环境能不能找到它。
所以只要你写出了一个正常的 .py 文件,比如:
tools.pybook.pystring_utils.pyuser_service.py
那它们就都可能被别的文件导入。
这件事特别值得你真正想通。因为它意味着:
你写的代码,不一定只能在当前文件里用一次,它完全可以被组织成可复用能力。
从这一刻开始,你的代码就不只是“做完一道题”,而是开始具备“被再次使用”的可能。
三、先看一个最小完整例子
假设你有一个文件叫 my_math.py,内容如下:
defadd(a, b):return a + bdefmul(a, b):return a * b
然后你再写一个 main.py:
import my_mathprint(my_math.add(3, 5))print(my_math.mul(4, 6))
输出结果:
824
这里发生的事情其实非常简单。
你自己写了一个模块 my_math.py然后在另一个文件里把它导进来 最后复用了它里面的函数
这就是自定义模块最基础、最本质的使用方式。
你现在应该把这个感觉建立起来:
“自己写一个模块,再在别的文件里导入它”这件事,本身就是非常正常的 Python 开发方式。
四、为什么自定义模块特别重要
因为只要代码一多,你早晚会进入这种阶段:
有些函数别的地方也能用 有些类不应该只写死在当前脚本里 有些工具逻辑应该单独整理 有些配置和常量也应该独立管理
这时候,如果你还是所有内容全塞一个文件里,复用和维护都会越来越痛苦。
而自定义模块能帮你做什么?
把通用函数单独拿出来 把类单独整理出去 把工具逻辑和主流程分开 让不同文件之间通过导入协作
这本质上是在让代码越来越模块化。
所以自定义模块不是“附加技能”,而是代码开始走向像样结构之后的必经之路。
五、自定义模块最常放什么内容
通常还是那几类:
函数 类 变量或常量 少量辅助逻辑
比如一个 config.py 模块里,可能会放:
APP_NAME = '图书管理系统'MAX_BORROW_COUNT = 3
一个 book.py 模块里,可能放:
classBook: ...
一个 string_tools.py 模块里,可能放:
defclean_text(text): ...
这说明模块本质上并不挑内容。 它关心的是逻辑归类。
所以你在写自定义模块时,重点不在于“我是不是写得足够高级”,而在于:
这一组代码逻辑上是不是适合放在一起。
六、一个特别常见的误区:以为模块必须很复杂
不是。
很多人一听“自定义模块”,脑子里会自动觉得,那得写成一个很大的工具库才算模块。其实完全不是。
你哪怕只是写了一个文件,里面只有两个函数,只要它能被别的文件导入使用,它就是模块。
比如:
# string_tools.pydefto_upper(text):return text.upper()defto_lower(text):return text.lower()
这就已经是一个很正常的自定义模块了。
所以不要把“模块”想得太正式。 模块不是规模概念,而是组织方式概念。
七、当一个模块写出来以后,你要开始考虑“别人怎么用”
这一点特别重要。
前面你写练习代码时,思路可能是:
我自己能跑通就行
但从自定义模块开始,你最好多加一个视角:
如果别人来导入我这个模块,他应该怎么用 他最需要哪些内容 模块名字是不是清楚 函数名字是不是直白 是否不该把无关代码也塞进去
也就是说,模块一旦打算被复用,它就不再只是“写给自己看的草稿”,而开始有“接口设计”的味道了。
这一步其实很关键。因为它会逼着你开始关注:
命名 边界 职责 可读性
这就是从练习代码走向项目代码的重要转折点之一。
八、什么叫包
模块已经讲清楚了,现在往前再走一步。
如果说:
一个 .py 文件是一个模块
那包你可以先这样理解:
一个用来组织多个模块的文件夹,就可以看作一个包。
也就是说:
模块解决的是“单个文件怎么组织代码” 包解决的是“多个相关模块怎么组织到一起”
举个很直观的例子。
假设你做一个图书系统,可能有这些文件:
book.pyuser.pylibrary.pyconfig.py
如果它们都散落在外面,文件一多就会显得杂。
这时候,你很自然就会想把它们放到一个文件夹里,比如叫:
library_system
这个文件夹里装着多个相关模块。 这时候,它就已经很像一个包了。
所以你可以先把包理解成:
装模块的文件夹。
九、为什么包会出现
因为项目继续长大之后,单靠模块已经不够了。
比如你以后可能会有:
和用户有关的模块 和图书有关的模块 和支付有关的模块 和工具函数有关的模块 和配置有关的模块
如果这些全都平铺在同一级目录里,时间一长也会乱。
所以包的意义就是进一步做分层整理。
比如你可以这样组织:
library_system/ book.py user.py library.py config.py
甚至将来再复杂一点,还可以按子目录继续分类。
所以包本质上是在解决比模块更大一级的组织问题。
十、先别把包想得太难,它就是“目录级组织”
这一点一定要先放轻松。
很多新手一看到“包”这个词,就会觉得进入高难区了。 其实在入门阶段,你完全可以先把它理解成:
为了更清楚地管理多个模块,我们把相关模块放进一个目录里。
这和你平时整理文件夹没什么本质区别。
比如你不会把照片、文档、音乐全扔桌面上。 你会建文件夹,把它们分类归档。
包做的就是同样的事情,只不过对象从普通文件换成了 Python 模块文件。
十一、模块和包的关系,可以这样记
这一组关系一定要理顺。
模块,是单个 .py 文件。 包,是用来装多个模块的目录。
你可以这样类比:
模块像一本书。 包像一个书架分类。
或者:
模块像一个房间。 包像一套房子。
所以不要把模块和包混成同一个东西。 它们是不同层级。
这个层级感一清楚,后面学导入路径时会轻松很多。
十二、一个很接地气的项目结构例子
比如我们把前面图书借阅项目稍微整理一下,可以长成这样:
library_system/ book.py user.py library.py utils.py main.py
这里:
book.py 是模块user.py 是模块library.py 是模块 整个 library_system 文件夹,可以理解成一个包级别的组织容器
这样一来,整个项目结构比把五六个文件全扔根目录里,要清楚得多。
而且你一眼就能看出来:
这些文件是同一个系统的一部分 它们不是随便散着的
这就是包最直接的实际价值。
十三、包里通常会放什么
在入门阶段,你可以先把包理解成“按主题归类的一组模块”。
比如:
一个图书系统包,里面放图书、用户、借阅逻辑 一个工具包,里面放字符串处理、文件处理、时间处理 一个数据分析包,里面放读数据、清洗数据、统计分析 一个爬虫包,里面放请求模块、解析模块、存储模块
所以包不是为了显得正式,而是因为:
一组模块本来就属于同一个主题或同一个子系统。
把它们放一起,是结构自然长出来的结果。
十四、为什么说“你的代码也可以被别人导入”这件事特别重要
因为它会改变你的写代码视角。
以前你写一段代码,可能只想着:
我把这次任务做完就行
但当你意识到“这段代码以后还可能被别的文件、别的项目、甚至别的人导入”时,你就会自然开始注意下面这些事:
模块名够不够清楚 函数名是不是能让人看懂 类的职责是否明确 有没有把不该暴露的内容也暴露出去 模块内部是否掺了太多无关逻辑
也就是说,模块和包不仅在整理代码,也在倒逼你写出更像“公共能力”的代码。
这会直接提升你的代码质量。
十五、一个很常见的问题:模块和包到底先学哪个
从学习顺序上说,一定是先模块,再包。
因为包只是更大一级的组织方式。 如果你连单文件模块都还没适应,那一上来讲包只会让脑子更乱。
所以你可以这样理解当前阶段:
先学会把代码拆成多个模块 再学会把多个模块归到一个包里 最后再学会更规范地在模块和包之间导入
这条路径是最自然的。
这一章重点,还是先把“自定义模块”和“包”的直觉建立起来。
十六、什么时候说明你真的需要包了
一个很实用的判断标准是:
当你的项目里已经不止三四个模块,而且这些模块还能明显分成几个主题区域时,就很适合开始考虑包。
比如你有:
用户相关模块 图书相关模块 订单相关模块 工具相关模块
这时候如果还全部平铺在一起,可读性就会明显下降。 而用包整理后,结构会一下清楚很多。
所以包不是一开始就必须上的。 它更像是在项目继续长大后,自然长出来的整理需求。
十七、你现在先不用死抠包的所有细节
这一点特别重要。
包这个话题,后面一深入会涉及:
导入路径 相对导入 绝对导入__init__.py包初始化行为
这些都是真实存在的内容。 但你现在这一章,不需要一次吃太深。
你当前最重要的是先把两件事想清楚:
我自己写的 .py 文件,本身就可以是模块 多个相关模块放进同一个目录里,就开始有包的味道了
只要这两条立住,后面学更细节的导入方式时,你就不会悬空。
十八、一个很实用的思维升级
从这一章开始,你最好慢慢建立一种新习惯:
写代码时,不只想“这一段怎么写”,还要想“这一段应该放在哪个文件里”“这个文件又属于哪一组模块”。
这就是典型的结构感。
比如你写了一个处理字符串的函数,别急着先塞主程序。 先想,它是不是应该进 string_tools.py。
你写了一个和图书对象有关的类,别先扔 main.py。 先想,它是不是应该进 book.py。
当你开始这样想问题时,你就已经不再只是在写代码,而是在组织项目。
这一步非常关键。
十九、本章小练习
你可以做两个特别适合入门的练习。
第一个练习:
自己写一个 my_string.py 文件,里面放两个函数:
reverse_text(text)把字符串反转
count_words(text)统计空格分隔后的单词数
然后在另一个文件里导入并使用它。
第二个练习:
把你前面写过的图书类、用户类,分别拆到不同文件里。 再建一个总目录,把这些文件都放进去。 你暂时不需要追求多复杂,重点是亲手感受一下:
当多个模块开始被装进一个目录后,整个小项目是不是立刻更像样了。
这个感觉,只有自己动手整理一次才会特别明显。
二十、本章总结
这一章最重要的,是把“自定义模块”和“包”的直觉真正建立起来。
你自己写的 .py 文件,只要能被别的文件导入使用,它就是自定义模块。 模块不是官方专属能力,而是你自己就能写出来的代码组织方式。 包可以先理解成用来组织多个相关模块的目录。 模块解决单文件层面的代码组织,包解决多模块层面的结构管理。 学会自定义模块和包,意味着你的代码开始从“写一个脚本”走向“搭一个小项目”。 这一步不仅改变文件结构,也会改变你写代码时的思考方式。
下一章我们继续往前走,进入一个很多人第一次看到会有点困惑、但非常重要的内容:084|__name__ == "__main__" 到底有什么用。