跳过正文
  1. Posts/

python使用pip之setup.py编写

·1167 字·3 分钟· loading · loading · · ·
ICE345
作者
ICE345
CS Student | System | Linux | OCaml

1. 基础结构
#

setup.py 是 Python 打包的核心配置文件,需使用 setuptools 库定义包的元数据和构建规则。

基本模板
#

from setuptools import setup, find_packages

setup(
    name="your-package-name",   # 包名(PyPI唯一标识)
    version="0.1.0",           # 版本号
    author="Your Name",
    author_email="[email protected]",
    description="Short description",
    long_description=open("README.md").read(),  # 长描述(README内容)
    long_description_content_type="text/markdown",  # README格式
    url="https://github.com/yourusername/your-package",  # 项目地址
    packages=find_packages(),  # 自动发现包目录
    install_requires=[],       # 依赖库列表
    entry_points={},           # 命令行工具入口
    classifiers=[],            # PyPI分类标签
    python_requires=">=3.6",   # Python版本要求
)

2. 关键参数详解
#

(1) name
#

  • 作用:包在 PyPI 上的唯一标识符。
  • 规则
    • 必须全小写,可用连字符(-),如 my-package
    • 需在 PyPI 上未被占用(上传前检查)。

(2) version
#

  • 作用:包的版本号,每次更新必须递增。
  • 格式:推荐语义化版本(如 1.0.0, 0.2.5)。

(3) packages
#

  • 作用:指定包含的 Python 包目录。
  • 自动发现
    packages=find_packages(),  # 自动搜索所有含 __init__.py 的目录
  • 手动指定
    packages=["my_package", "my_package.submodule"],

(4) install_requires
#

  • 作用:定义包的依赖库及版本约束。
  • 示例
    install_requires=[
        "requests>=2.25.1",    # 最低版本
        "numpy<1.22,>=1.20",   # 版本范围
        "pandas",              # 不限制版本
    ]

(5) entry_points
#

  • 作用:定义命令行工具入口,生成可执行命令。
  • 示例
    entry_points={
        "console_scripts": [
            "my-command=my_package.module:main",  # 格式:命令名=包.模块:函数
        ],
    }
    • 用户安装后可直接运行 my-command

(6) package_data
#

  • 作用:包含包内的非代码文件(如数据、配置文件)。
  • 示例
    package_data={
        "my_package": ["data/*.csv", "templates/*.html"],
    },

(7) include_package_data
#

  • 作用:自动包含 MANIFEST.in 中指定的文件。
  • 用法
    include_package_data=True,  # 需配合 MANIFEST.in 文件

(8) classifiers
#

  • 作用:为 PyPI 提供包的分类标签(便于搜索)。
  • 常用选项
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
        "Topic :: Software Development :: Libraries",
    ]

3. 完整示例
#

假设项目结构如下:

my_project/
├── my_package/
│   ├── __init__.py
│   ├── main.py
│   └── data/
│       └── config.json
├── README.md
├── LICENSE
└── setup.py

对应的 setup.py

from setuptools import setup, find_packages

setup(
    name="my-awesome-tool",
    version="0.1.0",
    author="Jane Doe",
    author_email="[email protected]",
    description="A tool to do awesome things.",
    long_description=open("README.md").read(),
    long_description_content_type="text/markdown",
    url="https://github.com/janedoe/my-awesome-tool",
    packages=find_packages(),
    install_requires=[
        "requests>=2.25.1",
        "click>=8.0.0",  # 命令行库
    ],
    entry_points={
        "console_scripts": [
            "awesome-tool=my_package.main:cli",  # 假设 main.py 有 cli() 函数
        ],
    },
    package_data={
        "my_package": ["data/*.json"],  # 包含 data 目录下的 JSON 文件
    },
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires=">=3.7",
)

4. 包含额外文件:MANIFEST.in
#

如果需要包含包外的文件(如文档、测试数据),需创建 MANIFEST.in 文件:

include LICENSE README.md
recursive-include docs *
recursive-include tests *

5. 验证与打包
#

(1) 生成分发包
#

pip install setuptools wheel  # 确保工具已安装
python setup.py sdist bdist_wheel  # 生成源码包和二进制包
  • 生成文件在 dist/ 目录。

(2) 本地测试安装
#

pip install .  # 在当前目录安装包
awesome-tool   # 测试命令行工具

6. 关键注意事项
#

  1. 包名唯一性:在 PyPI 搜索确认包名未被占用。
  2. 版本号递增:每次更新代码后需修改 version
  3. 依赖管理:精确指定依赖版本,避免未来更新导致兼容性问题。
  4. 许可证:必须包含 LICENSE 文件,并在 classifiers 中声明。
  5. 入口函数:确保 entry_points 指向的函数已正确定义。

通过以上步骤,你可以编写一个完整的 setup.py 文件,为发布到 PyPI 做好准备。


7. 提一嘴之生成可执行文件
#

使用工具如 PyInstaller 或 cx_Freeze 将Python脚本转换为独立的可执行文件:

1. 使用 PyInstaller
#

  • 安装
pip install pyinstaller
  • 生成可执行文件
pyinstaller --onefile your_script.py
  • --onefile 生成单个可执行文件。

  • 输出在 dist/ 目录中。

  • 跨平台:需在目标操作系统下分别打包。

2. 注意事项
#

  • 依赖处理:PyInstaller会自动分析脚本依赖,但某些复杂情况(如动态导入)可能需要手动配置(使用 .spec 文件)。

  • 文件大小:因包含Python解释器和依赖库,生成文件较大。

相关文章