Python篇---包
制作 Python 包(Package)其实就是把一组相关的代码(模块、函数、类等)打包成一个可复用的文件夹,方便自己或别人使用。就像把相关的工具放进一个标好名字的工具箱里,既整齐又方便拿取。下面用通俗的方式介绍包的制作和常用功能。
一、什么是 “包”?
简单说,包就是一个带 __init__.py
文件的文件夹。这个文件夹里可以放多个 .py
模块文件(比如 module1.py
、module2.py
),还可以嵌套子文件夹(子包)。
例:一个简单的包结构
mytools/ # 包的根目录
├── __init__.py # 包的标识文件(必须有,内容可以为空)
├── calculator.py # 模块1:计算器功能
├── formatter.py # 模块2:格式化功能
└── utils/ # 子包├── __init__.py # 子包的标识文件└── helper.py # 子包的模块:辅助功能
有了这个结构,你就可以在代码中用 import mytools
来导入整个包,使用里面的功能了。
二、如何制作一个包?
制作包的核心是 “搭好文件夹结构 + 写好 __init__.py
”,步骤很简单:
1. 创建包的文件夹结构
按功能划分模块,放进对应的文件夹。比如做一个处理数据的包 datatools
:
datatools/
├── __init__.py
├── cleaner.py # 数据清洗功能
├── analyzer.py # 数据分析功能
└── io/ # 子包:输入输出├── __init__.py├── reader.py # 读取文件└── writer.py # 写入文件
2. 编写 __init__.py
文件
这个文件是包的 “说明书”,告诉 Python 这个文件夹是一个包,还可以控制导入行为。最简单的 __init__.py
可以是空文件,但我们通常会加点配置让包更好用。
例:datatools/__init__.py
基础配置
# 声明这个包的版本
__version__ = "1.0.0"# 当用户用 "from datatools import *" 时,允许导入这些模块
__all__ = ["cleaner", "analyzer", "io"]
3. 编写模块代码
在每个 .py
文件里写具体功能。比如 cleaner.py
:
# datatools/cleaner.py
def remove_empty(data):"""删除空值"""return [x for x in data if x is not None]def normalize_duplicates(data):"""去重"""return list(set(data))
4. 测试包是否可用
在包的同级目录(和 datatools
同级)新建一个 test.py
,试试导入:
# test.py
from datatools.cleaner import remove_emptydata = [1, None, 2, None, 3]
print(remove_empty(data)) # 输出 [1, 2, 3]
运行 python test.py
,如果正常输出,说明包制作成功!
三、包的常用功能(让包更好用)
光搭好结构还不够,用好这些技巧能让你的包更专业、更易用。
1. 用 __all__
控制 “*” 导入
当用户用 from 包名 import *
时,默认只会导入 __init__.py
中定义的变量。通过 __all__
可以指定允许用户 “通配符导入” 时能拿到哪些模块 / 功能。
例:datatools/io/__init__.py
# 允许 "from datatools.io import *" 导入 reader 和 writer
__all__ = ["reader", "writer"]
这样用户执行 from datatools.io import *
时,就能直接用 reader
和 writer
模块了。
2. 在 __init__.py
中 “偷懒”:提前导入常用功能
如果包的层级较深(比如 datatools.io.reader.read_csv
),用户每次用都要写很长的路径,体验不好。可以在 __init__.py
中提前把常用功能导入到上层,简化使用。
例:datatools/__init__.py
# 提前用户不用 "from datatools import read_csv",而不用写全路径
from .io.reader import read_csv
from .cleaner import remove_empty # 直接用户直接用 remove_empty__all__ = ["read_csv", "remove_empty", "analyzer", "io"] # 记得加到 __all__ 里
现在用户可以直接这样用:
from datatools import read_csv, remove_empty
data = read_csv("data.csv") # 不用写 datatools.io.reader.read_csv 了
3. 子包的相对使用
子包(比如 datatools/io
)的用法和主包一样,可以嵌套多层,方便按功能细分。
例:调用子包功能
# 方法1:全路径导入
from datatools.io.writer import write_excel
write_excel("result.xlsx", data)# 方法2:先导入子包,再调用
import datatools.io.writer
datatools.io.writer.write_excel("result.xlsx", data)
4. 给包加版本号和说明
在 __init__.py
中定义 __version__
和 __doc__
,方便用户了解包的信息。
例:datatools/__init__.py
__version__ = "1.0.0"
__doc__ = """
datatools:一个简单的数据处理工具包
功能包括:数据清洗、分析、文件读写等
"""
用户可以这样查看:
import datatools
print(datatools.__version__) # 输出 1.0.0
print(datatools.__doc__) # 输出包的说明
5. 让包支持命令行调用
如果想让用户直接在命令行用你的包(比如 python -m datatools
),可以在 __main__.py
中写入口逻辑(和 __init__.py
同级)。
例:datatools/__main__.py
import sys
from .cleaner import remove_emptydef main():if len(sys.argv) > 1:data = sys.argv[1:] # 获取命令行参数print("处理后:", remove_empty(data))else:print("请输入数据!")if __name__ == "__main__":main()
现在用户可以在命令行运行:
python -m datatools a None b None
# 输出:处理后: ['a', 'b']
四、如何分享你的包?
做好的包可以分享给别人,最简单的方式是:
- 把整个包文件夹发给对方;
- 让对方把文件夹放在自己的项目目录下,或者加入 Python 的搜索路径(
sys.path
)。
如果想发布到 PyPI(让所有人用 pip install
安装),需要多做一些配置(比如写 setup.py
),但这是进阶内容了,新手先掌握本地包的制作和使用即可。
总结
制作包的核心是 “文件夹 + __init__.py
”,常用技巧包括:
- 用
__all__
控制通配符导入; - 在
__init__.py
中提前导入常用功能,简化用户调用; - 用子包细分功能,让结构更清晰;
- 加版本号和说明,提升专业性;
- 用
__main__.py
支持命令行调用。
包的本质是 “代码的组织方式”,目的是让代码更整洁、更易复用。刚开始不用追求复杂,先试着把自己常用的工具函数打包起来,慢慢就熟练了~