在Python世界里打包和分发你的代码是件既重要又令人头疼的事。幸好,我们有了setuptools这个超级实用的工具!今天就带大家彻底掌握这个Python生态系统中不可或缺的包构建工具。(不懂setuptools怎么好意思说自己会Python呢?)
setuptools是Python的一个包管理工具,它极大地简化了Python包的构建、打包和分发过程。你知道那些可以用pip install xxx安装的包吗?它们很可能就是用setuptools打包的!
setuptools是distutils的增强版,提供了更多功能和更好的兼容性。它让你能够:
简单来说:setuptools让你的Python代码可以被全世界的开发者使用!
想象一下,你写了一个超酷的函数库,能够: 1. 快速处理图像 2. 解析复杂数据 3. 或者实现了什么令人惊叹的算法
然后呢?你怎么分享给别人?通过电子邮件发送代码文件?还是放在GitHub让别人手动下载?
这就是setuptools大显身手的时候!它让你的代码可以:
首先,我们来创建一个简单的项目结构:
my_awesome_package/ ├── my_awesome_package/ │ ├── __init__.py │ └── core.py ├── setup.py └── README.md
注意看这个结构!最外层的文件夹是项目根目录,里面有一个同名的包目录,这是Python包的标准结构。
setup.py是整个包配置的核心。这个文件告诉setuptools如何构建和安装你的包。
下面是一个基本的setup.py例子:
```python from setuptools import setup, find_packages
setup( name="my_awesome_package", version="0.1.0", author="Your Name", author_email="your.email@example.com", description="A short description of your package", long_description=open("README.md").read(), long_description_content_type="text/markdown", url="https://github.com/yourusername/my_awesome_package", packages=find_packages(), classifiers=[ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], python_requires=">=3.6", install_requires=[ "numpy>=1.18.0", "pandas>=1.0.0", ], ) ```
这段代码看起来很多,但别担心!让我们一步步解析:
name:包的名称。这就是用户使用pip install时需要输入的名称。选个好名字很重要!
version:版本号。遵循语义化版本(Semantic Versioning)是个好习惯。
author和author_email:就是你的名字和邮箱啦!
description:简短描述,会显示在PyPI页面上。
long_description:详细描述,通常从README.md文件读取。
packages:包含的Python包。find_packages()会自动找到所有包,超级方便!
classifiers:包的分类标签,帮助用户在PyPI上找到你的包。完整列表可以在这里找到。
python_requires:支持的Python版本。
install_requires:依赖项列表。这超级重要!当用户安装你的包时,pip会自动安装这些依赖。
find_packages()是个非常有用的函数!它会自动查找所有包含__init__.py文件的目录。
如果你的包结构更复杂,你可以自定义搜索:
python find_packages(exclude=["tests", "docs"])
这样就会排除tests和docs目录。
依赖管理是包构建中最重要的部分之一!在install_requires中,你可以指定:
python install_requires=[ "requests>=2.25.0,<3.0.0", # 大于等于2.25.0但小于3.0.0 "numpy", # 任何版本的numpy "pandas>=1.0.0", # 大于等于1.0.0的pandas ]
你还可以指定可选依赖:
python extras_require={ "dev": ["pytest", "black", "flake8"], "visualization": ["matplotlib", "seaborn"], }
这样用户可以选择性安装这些依赖:
pip install my_awesome_package[dev] # 安装开发依赖 pip install my_awesome_package[visualization] # 安装可视化依赖
真是太方便了!!!
有时你的包需要包含非Python文件,比如配置文件、模板或资源。有两种方法可以做到:
创建一个MANIFEST.in文件:
include README.md include LICENSE recursive-include mypackage/data *.json *.csv
然后在setup.py中添加:
python setup( # ...其他参数... include_package_data=True, )
直接在setup()中指定:
python setup( # ...其他参数... package_data={ "mypackage": ["data/*.json", "data/*.csv"], }, )
准备好分享你的包了吗?这里是步骤:
bash pip install setuptools wheel twine
bash python setup.py sdist bdist_wheel
这会创建两种分发格式: - sdist:源码分发(.tar.gz文件) - bdist_wheel:编译分发(.whl文件)
这两个文件会被放在dist/目录下。
先在TestPyPI上测试(强烈推荐!):
bash twine upload --repository-url https://test.pypi.org/legacy/ dist/*
确认一切正常后,上传到真正的PyPI:
bash twine upload dist/*
恭喜!现在世界各地的人都可以用pip install your-package安装你的包了!(这感觉真是太棒了!)
随着你的包变得更复杂,setup.py可能会变得很长。这时可以考虑使用setup.cfg文件:
```ini [metadata] name = my_awesome_package version = 0.1.0 author = Your Name author_email = your.email@example.com description = A short description of your package long_description = file: README.md long_description_content_type = text/markdown url = https://github.com/yourusername/my_awesome_package classifiers = Programming Language :: Python :: 3 License :: OSI Approved :: MIT License Operating System :: OS Independent
[options] packages = find: python_requires = >=3.6 install_requires = numpy>=1.18.0 pandas>=1.0.0 ```
然后你的setup.py可以简化为:
```python from setuptools import setup
setup() ```
这种分离配置和代码的方式使你的项目结构更清晰!
Python包构建正在向pyproject.toml标准过渡。这是PEP 517和PEP 518引入的新标准。
基本的pyproject.toml文件看起来像这样:
```toml [build-system] requires = ["setuptools>=42", "wheel"] build-backend = "setuptools.build_meta"
[project] name = "my_awesome_package" version = "0.1.0" authors = [ {name = "Your Name", email = "your.email@example.com"}, ] description = "A short description of your package" readme = "README.md" requires-python = ">=3.6" classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ] dependencies = [ "numpy>=1.18.0", "pandas>=1.0.0", ]
[project.urls] "Homepage" = "https://github.com/yourusername/my_awesome_package" "Bug Tracker" = "https://github.com/yourusername/my_awesome_package/issues" ```
虽然这是未来的趋势,但目前setuptools仍然是最广泛使用的工具。掌握setuptools,你就掌握了Python包构建的核心知识!
```python
version = "0.1.0" ```
然后在setup.py中读取:
```python import re with open("my_awesome_package/init.py", "r") as f: version = re.search(r'version = "(.*?)"', f.read()).group(1)
setup( # ... version=version, # ... ) ```
开发模式安装:在开发过程中,使用pip install -e .安装你的包,这样你可以边开发边测试,而不需要重新安装。
测试与CI集成:在setup.py中添加测试配置:
python setup( # ... test_suite="tests", # ... )
确保每个子目录都有__init__.py文件,即使它是空的。
尽量使用灵活的版本需求,例如requests>=2.0.0而不是requests==2.25.1。
检查你的包结构和find_packages()配置,确保所有必要的目录都被包含。
setuptools是Python生态系统中不可或缺的工具。掌握它,你就能够创建专业的Python包,与全世界分享你的代码。
从简单的setup.py开始,逐步添加更多功能,你的包会变得越来越完善。记住,好的包不仅仅是好的代码,还包括好的文档、测试和用户体验。
希望这篇教程能帮助你开始使用setuptools!打包快乐!
(如果你对其他Python工具感兴趣,不妨探索一下pytest, black, mypy等优秀工具,它们会让你的Python开发更上一层楼!)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。