包(package)

包的基本概念

一个包含多个模块和子包的目录。

创建包

  • 创建一个目录,其名称即为包的名称。例如,创建一个名为 mypackage 的目录。

  • 添加__init.py_文件

    • 在 mypackage 目录下创建一个名为__init__.py的文件。这个文件可以是空的,也可以包含 Python 代码。

  • 作用:

    • 标志性:告诉 Python 解释器这个目录是一个包,而不是一个普通目录。在 Python3.3+ 的“隐式命名空间包”出现前,这是必须的。

    • 初始化:当包被首次导入时,该文件中的代码会被执行一次。可用于执行包的初始化操作。

    • 控制导入:通过定义__all__变量来控制 from package import *时导入哪些模块。

    • 简化导入:可以其中导入子模块,使得用户可以使用更短的导入路径。

  • 添加模块和子包

    • 将你的.py模块文件放入 mypackage 目录。

    • 你也可以在 mypackage 内创建子目录(如 subpackage),并在其中放入__init__.py和模块,形成子包。

mypackage/
├── __init__.py  # 包的初始化文件
├── module1.py
├── module2.py
└── subpackage/  # 子包
    ├── __init__.py
    └── module3.py

导入包中的内容

  • 导入整个包

    • import mypackage

    • 这回执行mypackage/__iniit__.py中的代码。

    • 要访问包内的模块,需要完整的路径:mypackage.module1.some_function()

  • 导入包中特定模块

    • from mypackage import module1

    • from mypackage import module1, module2

    • 导入后可以直接使用module.some_function

  • 从包中的模块导入特定对象

    • from mypackage.module1 import some_function

    • from mypackage.module1 import some_function as func

    • 导入后,可以直接使用 some_function()

  • 导入子包

    • import mypackage.subpackage

    • from mypackage import subpackage

    • from mypackage.subpackage import module3

__init__.py文件的高级用法

  • __all__ 是一个字符串列表,用于明确指定当用户执行 from package_name import * 时,应该从该包中导入哪些名称(模块、函数、类、变量等)

  • 如果定义了 __all__from package import * 将只导入 __all__ 列表中列出的名称。

  • 如果未定义 __all__from package import * 会导入该包的命名空间中所有不以下划线 _ 开头的名称。这通常包括在 __init__.py 中定义的变量、函数、类,以及通过 import module 语句导入的模块名。

# mypackage/__init__.py

# 定义一些变量和函数
internal_var = "内部变量,不希望被 * 导入"
public_var = "公共变量"

def internal_func():
    pass

def public_func():
    pass

# 导入子模块
import mypackage.module1
import mypackage.module2

# 定义 __all__
__all__ = [
    'public_var',      # 导入公共变量
    'public_func',     # 导入公共函数
    'module1',         # 导入 module1 模块
    'Calculator'       # 注意:Calculator 还未定义,见下一点
]

相对导入和绝对导入

  • 绝对导入(推荐):基于项目根目录

form mypackage import module1
  • 相对导入:基于当前包位置,用.表示当前目录

from . import module1      # 当前包下的 module1
from .. import subpkg      # 上一级包下的 subpkg

相对导入只在包内模块使用,不能直接在脚本入口使用。

安装和发布包

  • 本地安装包:

pip install .
  • 构建与发布(推荐使用setuptoolspoetry)

python setup.py sdist bdist_wheel
pip install dist/mypkg-0.1-py3-none-any.whl

常见元数据文件:

  • setup.py / pyproject.toml → 包的配置

  • requirements.txt → 依赖

  • MANIFEST.in → 控制打包时包含的文件

最后更新于