15. python项目部署与打包

15. 部署与打包


15.1 使用setuptools打包项目

setuptools是Python官方推荐的打包工具,支持源码分发、Wheel包生成及依赖管理。


1. 基础项目结构

假设项目目录结构如下:

myproject/  
├── myproject/  
│   ├── __init__.py  
│   ├── core.py  
│   └── utils.py  
├── setup.py  
└── README.md  

2. 编写setup.py配置文件
from setuptools import setup, find_packages

setup(
    name="myproject",                     # 项目名称(PyPI唯一标识)
    version="0.1.0",                      # 版本号(遵循语义化版本规范)
    author="Your Name",                   
    author_email="[email protected]",
    description="A short description",    
    long_description=open("README.md").read(),  # 长描述(支持Markdown)
    long_description_content_type="text/markdown",
    url="https://github.com/yourname/myproject",  
    packages=find_packages(),             # 自动发现所有包(含子包)
    install_requires=[                    # 依赖库列表
        "requests>=2.25",
        "numpy>=1.20"
    ],
    classifiers=[                         # PyPI分类标签
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires=">=3.8",              # Python版本要求
    entry_points={                        # 命令行入口配置
        "console_scripts": [
            "mycli=myproject.cli:main"    # 命令名=模块路径:函数
        ]
    },
    include_package_data=True,            # 包含非代码文件(需配合MANIFEST.in)
)

3. 添加非代码文件
  • 步骤1:创建MANIFEST.in文件,定义需要包含的静态文件:

    include README.md
    recursive-include myproject/data *.csv
    
  • 步骤2:在setup.py中设置include_package_data=True


4. 生成分发包

运行以下命令生成源码包(.tar.gz)和Wheel包(.whl):

python setup.py sdist bdist_wheel

生成文件位于dist/目录:

dist/
├── myproject-0.1.0.tar.gz     # 源码包
└── myproject-0.1.0-py3-none-any.whl  # Wheel包

5. 上传到PyPI
  1. 安装twine

    pip install twine
    
  2. 上传包

    twine upload dist/*  # 首次上传需输入PyPI账号密码
    
  3. 用户安装

    pip install myproject
    

6. 高级配置
  • 依赖扩展

    extras_require={
        "dev": ["pytest>=6.0"],          # 开发依赖:pip install myproject[dev]
        "plot": ["matplotlib>=3.5"]      # 可选功能依赖
    }
    
  • C扩展支持

    from setuptools import Extension
    
    extensions = [
        Extension(
            name="myproject._speedup",   # 模块名称
            sources=["src/speedup.c"]    # C源码文件
        )
    ]
    
    setup(ext_modules=extensions)
    

15.2 生成可执行文件(PyInstaller)

PyInstaller可将Python脚本打包为独立可执行文件,支持Windows、macOS和Linux。


1. 基础使用
  • 安装PyInstaller

    pip install pyinstaller
    
  • 打包单文件应用

    pyinstaller --onefile app.py  # 生成单个exe(Windows)或可执行文件(macOS/Linux)
    

    输出文件位于dist/目录。


2. 处理依赖问题
  • 添加隐藏依赖:若代码中存在动态导入(如插件系统),需手动指定:

    pyinstaller --hidden-import=module_name app.py
    
  • 包含数据文件

    pyinstaller --add-data "src/data:data" app.py  # 格式为"源路径:目标路径"
    

3. 高级配置(.spec文件)
  • 生成.spec文件

    pyinstaller --name=myapp app.py  # 生成myapp.spec
    
  • 编辑.spec文件

    # myapp.spec
    a = Analysis(
        ['app.py'],
        pathex=[],                   # 搜索路径
        binaries=[],                 # 二进制依赖(如.dll/.so)
        datas=[('config.yaml', '.')],# 数据文件(目标路径为根目录)
        hiddenimports=['sklearn'],   # 显式声明隐藏依赖
        hookspath=[],                # 自定义钩子路径
        runtime_hooks=[],
        excludes=[],                 # 排除模块(减少体积)
        win_no_prefer_redirects=False,
        win_private_assemblies=False,
        cipher=None,
        noarchive=False,
    )
    
    pyz = PYZ(a.pure, a.zipped_data)
    exe = EXE(
        pyz,
        a.scripts,
        a.binaries,
        a.zipfiles,
        a.datas,
        name='myapp',                # 输出名称
        debug=False,                 # 禁用调试信息
        bootloader_ignore_signals=False,
        strip=False,
        upx=True,                    # 使用UPX压缩(需安装UPX)
        console=True,                # 是否显示控制台(Windows)
        icon='app.ico'               # 设置图标(Windows)
    )
    
  • 根据.spec文件重新打包

    pyinstaller myapp.spec
    

4. 常见问题解决
问题 解决方案
反病毒软件误报 使用代码签名证书签名可执行文件
动态库加载失败 通过--add-binary "libfoo.so:."显式添加二进制文件
路径问题 在代码中使用sys._MEIPASS访问打包后的数据文件:
base_path = getattr(sys, '_MEIPASS', os.path.dirname(__file__))
打包后体积过大 使用--exclude-module排除无用模块(如numpy.testing

5. 跨平台打包注意事项
  • Windows
    • 使用--icon=app.ico设置图标。
    • 若需隐藏控制台窗口,添加--windowed参数。
  • macOS
    • 生成.app包:pyinstaller --windowed --name=MyApp app.py
    • 签名应用:codesign --deep -s "Developer ID" dist/MyApp.app
  • Linux
    • 解决glibc版本兼容性问题,建议在低版本系统(如CentOS 7)中打包。

总结

通过setuptools可实现Python项目的标准化打包与分发,而PyInstaller则能将脚本转换为跨平台可执行文件。关键点:

  1. setuptools:需完整配置setup.py,管理依赖和元数据,支持上传到PyPI。
  2. PyInstaller:通过.spec文件精细控制打包过程,解决路径和依赖问题,适配不同操作系统。

你可能感兴趣的:(15. python项目部署与打包)