Python导包、分包与打包的完整教程

作者:

文章目录
  • 目录
    • 第一部分:Python导包基础(完全新手友好)
      • 第一章:理解Python中的“包”和“模块”
      • 第二章:最简单的导包方式
      • 第三章:理解绝对导入和相对导入
      • 第四章:init.py 文件的妙用
    • 第二部分:项目分包实践(结构化思维)
      • 第五章:从小项目到中大型项目的演变
    • 第三部分:打包成可执行文件(无需Python环境运行)
      • 第七章:为什么需要打包成exe?
      • 第八章:使用PyInstaller(最简单、最流行)
      • 第九章:使用spec文件进行高级控制
      • 第十章:使用cx_Freeze(跨平台替代方案)
      • 最佳实践指南

    1.1 什么是模块?

    # 一个.py文件就是一个模块
    # example.py 就是一个名为example的模块
    def say_hello():
        print("你好!")
    
    
    def add(a, b):
        return a + b
    

    1.2 什么是包?

    # 包是一个包含__init__.py文件的文件夹
    my_package/
        __init__.py    # 这个文件让Python知道这是包
        module1.py
        module2.py
    

    2.1 同一个文件夹内的导入

    项目结构:
    project/
        main.py
        utils.py
    
    # utils.py
    def greet(name):
        return f"你好,{name}!"
    
    
    def calculate_sum(numbers):
        return sum(numbers)
    
    # main.py - 方法1:导入整个模块
    import utils
    
    result = utils.greet("小明")
    print(result)  # 输出:你好,小明!
    
    total = utils.calculate_sum([1, 2, 3, 4, 5])
    print(total)   # 输出:15
    
    # main.py - 方法2:导入特定功能
    from utils import greet, calculate_sum
    
    result = greet("小红")  # 直接使用,不用加 utils.
    print(result)
    
    # main.py - 方法3:导入并重命名
    from utils import greet as say_hello
    
    say_hello("小张")  # 使用新名字
    

    2.2 导入外部库

    # Python内置库
    import math
    import random
    import datetime
    
    # 第三方库(需要先安装)
    # pip install requests
    import requests
    

    3.1 创建多级目录结构

    my_project/
    │   main.py
    │
    ├───database/
    │   │   __init__.py
    │   │   connector.py
    │   │   models.py
    │
    └───utils/
        │   __init__.py
        │   math_tools.py
        │   string_tools.py
    

    3.2 绝对导入(推荐新手使用)

    # main.py
    from database.connector import connect_db
    from utils.math_tools import add_numbers
    from utils.string_tools import format_text
    

    3.3 相对导入(在包内部使用) 若直接运行的是models.py

    # 在 database/models.py 中
    from .connector import connect_db    # . 表示同一目录
    from ..utils.math_tools import add_numbers  # .. 表示上级目录
    

    若直接运行的是main.py

    # 在 database/models.py 中
    from database.connector import connect_db    # 与main同一目录
    from utils.math_tools import add_numbers  # 与main同一目录
    

    4.1 最简单的 init.py

    # database/__init__.py
    # 空文件也可以,但有它才算是包
    

    4.2 有组织的 init.py

    # utils/__init__.py
    # 集中导入,方便外部使用
    from .math_tools import *
    from .string_tools import *
    
    
    # 或者更精确的控制
    __all__ = ['add_numbers', 'multiply_numbers', 'format_text']
    
    # 这样在外面就可以
    from utils import add_numbers  # 不需要知道math_tools的存在
    

    4.3 包级别的变量和初始化

    # utils/__init__.py
    # 包版本信息
    __version__ = "1.0.0"
    __author__ = "你的名字"
    
    
    # 包初始化代码
    print("正在加载工具包...")
    
    
    # 包级别的配置
    DEFAULT_CONFIG = {
        "log_level": "INFO",
        "timeout": 30
    }
    

    5.1 初级阶段:扁平结构

    simple_app/
        app.py          # 主程序
        config.py       # 配置
        helpers.py      # 辅助函数
        data.json       # 数据文件
    

    5.2 中级阶段:按功能分包

    medium_app/
    │   main.py                    # 程序入口
    │   requirements.txt           # 依赖列表
    │   README.md                 # 说明文档
    │
    ├───core/                     # 核心业务逻辑
    │   │   __init__.py
    │   │   calculator.py        # 计算器类
    │   │   validator.py         # 验证器
    │
    ├───ui/                       # 用户界面
    │   │   __init__.py
    │   │   window.py           # 主窗口
    │   │   widgets.py          # 小部件
    │
    ├───data/                     # 数据处理
    │   │   __init__.py
    │   │   loader.py           # 数据加载
    │   │   saver.py            # 数据保存
    │
    └───utils/                   # 通用工具
        │   __init__.py
        │   logger.py           # 日志工具
        │   formatter.py        # 格式化工具
    

    5.3 专业阶段:标准Python项目结构

    professional_app/
    │
    ├───src/                     # 源代码目录(推荐结构)
    │   └───my_app/              # 你的包名
    │       │   __init__.py
    │       │   __main__.py     # 命令行入口:python -m my_app
    │       │   cli.py          # CLI接口
    │       │   config.py       # 配置管理
    │       │
    │       ├───core/
    │       │   │   __init__.py
    │       │   │   business_logic.py
    │       │   │   models.py
    │       │
    │       ├───api/
    │       │   │   __init__.py
    │       │   │   routes.py
    │       │   │   handlers.py
    │       │
    │       └───utils/
    │           │   __init__.py
    │           │   helpers.py
    │           │   decorators.py
    │
    ├───tests/                   # 测试目录
    │   │   __init__.py
    │   │   test_core.py
    │   │   test_utils.py
    │   │   conftest.py         # pytest配置
    │
    ├───docs/                    # 文档
    │       index.md
    │       tutorial.md
    │
    ├───examples/               # 示例代码
    │       basic_usage.py
    │       advanced_features.py
    │
    ├───scripts/                # 脚本
    │       setup_env.py
    │       generate_data.py
    │
    │   .gitignore              # Git忽略文件
    │   pyproject.toml          # 项目配置(现代方式)
    │   setup.py               # 安装配置(传统方式)
    │   README.md              # 项目说明
    │   LICENSE               # 许可证
    └───requirements.txt       # 依赖包列表
    

    7.1 打包的好处

    • 用户无需安装Python
    • 可以直接双击运行
    • 保护源代码(可选)
    • 方便分发

    8.1 安装PyInstaller

    # 在命令行中执行
    pip install pyinstaller
    
    
    # 验证安装
    pyinstaller --version
    

    8.2 基本打包命令

    # 最简单的打包
    pyinstaller your_program.py
    
    
    # 打包后,在 dist/ 文件夹中找到可执行文件
    

    8.3 常用参数详解

    # 1. --onefile:打包成单个文件
    pyinstaller --onefile main.py
    
    
    # 2. --windowed:无控制台窗口(适合GUI程序)
    pyinstaller --windowed gui_app.py
    
    
    # 3. --icon:设置图标
    pyinstaller --onefile --windowed --icon=my_icon.ico main.py
    
    
    # 4. --name:指定输出文件名
    pyinstaller --name "我的应用" main.py
    
    
    # 5. --add-data:添加额外文件(如配置文件、图片)
    # Windows格式:源文件路径;目标路径
    # Linux/Mac格式:源文件路径:目标路径
    pyinstaller --add-data "config.ini;." main.py
    pyinstaller --add-data "images/*.png:images" main.py
    
    
    # 6. --hidden-import:添加隐藏的依赖
    pyinstaller --hidden-import=tkinter main.py
    

    8.4 实战:打包一个图形界面程序

    # 假设你有一个 tkinter 程序
    pip install pyinstaller
    
    
    # 进入项目目录
    cd your_project_folder
    
    
    # 打包命令
    pyinstaller --onefile --windowed --icon=app.ico --name "我的应用" ^
                --add-data "images;images" ^
                --add-data "config.ini;." ^
                main.py
    

    9.1 生成spec文件

    # 生成初始spec文件
    pyi-makespec main.py
    
    
    # 或者从已经打包的项目中复制
    

    9.2 spec文件详解

    # main.spec
    # -*- mode: python ; coding: utf-8 -*-
    
    
    a = Analysis(
        ['main.py'],  # 主程序文件
        pathex=[],    # 搜索路径
        binaries=[],  # 二进制文件
        datas=[       # 数据文件
            ('config.ini', '.'),
            ('images/*.png', 'images'),
            ('sounds/*.wav', 'sounds')
        ],
        hiddenimports=[  # 隐藏的依赖
            'tkinter',
            'PIL._tkinter_finder'
        ],
        hookspath=[],    # 钩子路径
        hooksconfig={},  # 钩子配置
        runtime_hooks=[],  # 运行时钩子
        excludes=[],     # 排除模块(减少体积)
        win_no_prefer_redirects=False,
        win_private_assemblies=False,
        cipher=None,     # 加密字节码
        noarchive=False  # 不打包成archive
    )
    
    
    # 打包成单个文件
    pyz = PYZ(a.pure, a.zipped_data, cipher=None)
    
    
    exe = EXE(
        pyz,
        a.scripts,
        [],
        exclude_binaries=True,
        name='我的应用',  # 输出文件名
        debug=False,
        bootloader_ignore_signals=False,
        strip=False,
        upx=True,        # 使用UPX压缩
        console=False,   # 显示控制台?True/False
        icon='app.ico',  # 图标
        disable_windowed_traceback=False,
        argv_emulation=False,
        target_arch=None,
        codesign_identity=None,
        entitlements_file=None
    )
    
    
    coll = COLLECT(
        exe,
        a.binaries,
        a.zipfiles,
        a.datas,
        strip=False,
        upx=True,
        upx_exclude=[],
        name='我的应用'  # 文件夹名称
    )
    

    9.3 使用spec文件打包

    # 使用spec文件打包
    pyinstaller main.spec
    

    10.1 安装和基本使用

    pip install cx-Freeze
    

    1. 使用src布局:将源代码放在src目录下
    2. 清晰的分层:按功能而不是按类型组织
    3. 最小化import:只导入需要的模块
    4. 使用__init__.py控制导出:明确公开的API
    5. 虚拟环境:在干净的虚拟环境中打包
    6. 测试打包结果:在另一台干净电脑上测试
    7. 版本控制:每次打包使用不同的版本号
    8. 签名和加密:商业应用考虑代码签名

    以上就是Python导包、分包与打包的完整教程的详细内容,更多关于Python导包、分包与打包的资料请关注风君子博客其它相关文章!

    您可能感兴趣的文章:

    • Python实用秘技之快速优化导包顺序详解
    • 全面解析python当前路径和导包路径问题
    • Python 手动导包的实现
    • python TCP Socket的粘包和分包的处理详解
    • Python轻松将脚本打包成EXE应用的6种方法实现与对比

    站内搜索