作为一个Python开发者,你可能经常使用pip install来安装各种第三方库。但有没有想过,自己的代码也能被全世界开发者轻松安装使用?我刚开始学Python时,看到别人能用一行命令安装我的代码,觉得简直是魔法。后来才知道,这背后的魔法就是PyPI(Python Package Index)。
PyPI是Python官方的软件仓库,目前托管着超过40万个开源项目。把你的代码发布到这里,意味着:
我发布第一个包时踩了不少坑,比如包名冲突、版本号混乱、依赖项缺失等问题。下面就把这些经验总结成一套完整的操作指南,让你避开这些"新手陷阱"。
一个标准的Python包至少包含以下内容:
code复制my_awesome_package/ # 项目根目录
├── my_awesome_package/ # 真正的包目录
│ ├── __init__.py
│ └── module1.py
├── tests/ # 测试目录(可选)
├── setup.py # 打包配置文件
├── README.md # 项目说明
└── LICENSE # 开源协议
这里有个容易混淆的点:项目根目录和包目录通常是同名的。比如我的时间处理包就采用这样的结构:
code复制time_utils/
├── time_utils/
│ ├── __init__.py
│ ├── datetime_utils.py
│ └── timestamp.py
└── setup.py
这个文件是Python识别文件夹为包的关键。它可以完全为空,但我建议至少包含:
python复制__version__ = "0.1.0" # 保持与setup.py一致
__all__ = ["module1"] # 控制from package import *的行为
# 可以在这里集中导入子模块功能
from .module1 import main_function
让我们以创建一个图片处理包为例:
python复制# image_processor/transform.py
from PIL import Image
def resize_image(input_path, output_path, size=(800, 600)):
"""调整图片尺寸"""
with Image.open(input_path) as img:
resized = img.resize(size)
resized.save(output_path)
记得在__init__.py中暴露这个功能:
python复制from .transform import resize_image
__all__ = ["resize_image"]
这个文件是打包的核心,来看一个增强版配置:
python复制from setuptools import setup, find_packages
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setup(
name="image-processor-toolkit", # 全局唯一,建议加个人标识
version="0.1.3", # 遵循语义化版本规范
author="Your Name",
author_email="your.email@example.com",
description="Advanced image processing toolkit",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/yourname/image-processor",
packages=find_packages(include=["image_processor*"]),
install_requires=[ # 生产环境依赖
"Pillow>=8.0.0"
],
extras_require={ # 可选依赖
"dev": ["pytest>=6.0"],
"aws": ["boto3>=1.0"]
},
classifiers=[
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires=">=3.7",
entry_points={ # 创建命令行工具
"console_scripts": [
"imgproc=image_processor.cli:main",
],
},
)
MIT协议是最常用的宽松协议,只需在LICENSE文件中添加:
code复制Copyright (c) [年份] [作者名]
Permission is hereby granted...
完整文本可从choosealicense.com获取。如果是公司项目,可能需要选择Apache 2.0等协议。
好的README应该包含:
使用Markdown增强可读性:
markdown复制# Image Processor Toolkit

处理图片的瑞士军刀,支持:
- 批量调整尺寸
- 格式转换
- 添加水印
## 安装
```bash
pip install image-processor-toolkit
python复制from image_processor import resize_image
resize_image("input.jpg", "output.jpg")
code复制
## 4. 打包与发布全流程
### 4.1 构建分发文件
首先确保安装了最新工具:
```bash
python -m pip install --upgrade setuptools wheel twine
生成发布文件:
bash复制# 在项目根目录执行
python setup.py sdist bdist_wheel
这会在dist目录生成.whl和.tar.gz文件。我建议每次发布前删除旧dist文件夹。
PyPI提供了测试环境(test.pypi.org),强烈建议先在这里练习:
bash复制python -m twine upload --repository testpypi dist/*
验证安装:
bash复制pip install --index-url https://test.pypi.org/simple/ your-package-name
bash复制python -m twine upload dist/*
上传成功后,你的包会在几分钟内出现在pypi.org。
遵循语义化版本规范:
我习惯在setup.py中使用:
python复制version = "1.2.3" # 明确指定
# 或者动态获取
from my_package import __version__
version = __version__
常见问题及解决方案:
pip check检测python复制install_requires = [
"numpy; python_version<'3.7'",
"numpy>=1.19; python_version>='3.7'"
]
使用GitHub Actions实现CI/CD:
yaml复制name: Publish Python Package
on:
release:
types: [created]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build package
run: python setup.py sdist bdist_wheel
- name: Publish
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: twine upload dist/*
记得在GitHub仓库设置中添加PYPI_TOKEN作为Secret。