Python自动化脚本打包与发布:从开发到部署
·
写完自动化脚本后,怎么分享给同事?怎么部署到服务器?打包发布是必须掌握的技能。这篇文章系统讲解Python脚本的打包、发布和分发方法。
一、打包基础:setup.py和pyproject.toml
传统方式:setup.py
from setuptools import setup, find_packages
setup(
name='my-automation',
version='1.0.0',
description='自动化脚本工具集',
author='Your Name',
author_email='your@email.com',
packages=find_packages(),
install_requires=[
'requests>=2.28.0',
'pandas>=1.5.0',
],
entry_points={
'console_scripts': [
'my-auto=my_automation.main:main',
],
},
python_requires='>=3.8',
classifiers=[
'Programming Language :: Python :: 3',
'License :: OSI Approved :: MIT License',
],
)
现代方式:pyproject.toml(推荐)
[build-system]
requires = ["setuptools>=45", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "my-automation"
version = "1.0.0"
description = "自动化脚本工具集"
readme = "README.md"
requires-python = ">=3.8"
license = {text = "MIT"}
authors = [
{name = "Your Name", email = "your@email.com"}
]
dependencies = [
"requests>=2.28.0",
"pandas>=1.5.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0.0",
"black>=22.0.0",
]
[project.scripts]
my-auto = "my_automation.main:main"
[tool.black]
line-length = 88
target-version = ['py38', 'py39', 'py310']
[tool.isort]
profile = "black"
二、打包成可执行文件
使用PyInstaller:打包成独立exe
# 安装
pip install pyinstaller
# 基本打包
pyinstaller --onefile your_script.py
# Windows下生成exe,Linux下生成可执行文件
# --onefile: 打包成单个文件
# --console: 显示控制台(无GUI时必须)
# --icon: 设置图标
# --name: 指定输出名称
高级打包配置:
# 带参数打包
pyinstaller \
--onefile \
--console \
--name "MyAutomation" \
--icon "app.ico" \
--add-data "config;config" \
--hidden-import=requests \
--collect-all pandas \
your_script.py
spec文件配置(复杂项目):
# automation.spec
from PyInstaller.utils.icons import collect_all_pyimg_icon
a = Analysis(
['src/main.py'],
pathex=[],
binaries=[],
datas=[
('config/*.json', 'config'),
('templates/*', 'templates'),
],
hiddenimports=['pkg_resources'],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=['tkinter'],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=None,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=None)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='MyAutomation',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
)
使用cx_Freeze:跨平台打包
# setup.py for cx_Freeze
from cx_Freeze import setup, Executable
build_options = {
'packages': ['requests', 'pandas'],
'excludes': ['tkinter'],
'include_files': ['config/', 'templates/'],
}
executables = [
Executable('src/main.py', base='Console', target_name='MyAutomation'),
]
setup(
name='MyAutomation',
version='1.0.0',
description='自动化脚本工具集',
options={'build_exe': build_options},
executables=executables,
)
# 打包
python setup.py build
三、打包成安装程序
使用HM Never Install:创建安装包
pip install hn
hn build --spec automation.spec
使用Inno Setup(Windows)
生成exe后,用Inno Setup创建安装程序:
[Setup]
AppName=MyAutomation
AppVersion=1.0.0
DefaultDirName={pf}\MyAutomation
OutputDir=installer
OutputBaseFilename=MyAutomation_Setup_v1.0.0
[Files]
Source: "dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
四、发布到PyPI
准备发布
# 安装发布工具
pip install build twine
# 构建源码包和wheel
python -m build
上传到PyPI
# 注册账号 https://pypi.org/
# 创建API Token
# 上传(测试)
twine upload --repository testpypi dist/*
# 上传(正式)
twine upload dist/*
使用API Token
# ~/.pypirc配置
[pypi]
username = __token__
password = pypi-xxxxxxxxxxxx
五、自动化打包脚本
写一个自动化打包脚本:
#!/usr/bin/env python3
"""
自动化打包脚本
"""
import os
import sys
import shutil
import subprocess
from pathlib import Path
from datetime import datetime
class AutoPackager:
def __init__(self, project_name, version='1.0.0'):
self.project_name = project_name
self.version = version
self.root_dir = Path(__file__).parent.resolve()
self.dist_dir = self.root_dir / 'dist'
self.build_dir = self.root_dir / 'build'
def clean(self):
"""清理构建目录"""
dirs_to_clean = ['dist', 'build', '__pycache__', '*.egg-info']
for pattern in dirs_to_clean:
for p in self.root_dir.rglob(pattern):
if p.is_dir():
print(f"删除目录: {p}")
shutil.rmtree(p, ignore_errors=True)
elif p.is_file():
print(f"删除文件: {p}")
p.unlink()
def build_wheel(self):
"""构建wheel包"""
print("构建wheel包...")
subprocess.run([sys.executable, '-m', 'build'], check=True)
print("✓ wheel包构建完成")
def build_exe(self):
"""打包成exe"""
print("打包成exe...")
subprocess.run([
'pyinstaller',
'--onefile',
'--console',
'--name', f"{self.project_name}_v{self.version}",
'--distpath', str(self.dist_dir),
'src/main.py'
], check=True)
print("✓ exe打包完成")
def create_zip(self):
"""创建zip分发包"""
print("创建zip包...")
zip_name = f"{self.project_name}_v{self.version}_{datetime.now():%Y%m%d}"
zip_path = self.dist_dir / zip_name
# 收集所有文件
files_to_package = []
for pattern in ['*.py', '*.txt', '*.md', 'config/**/*', 'templates/**/*']:
files_to_package.extend(self.root_dir.glob(pattern))
shutil.make_archive(str(zip_path), 'zip', self.root_dir, '.')
print(f"✓ zip包创建完成: {zip_path}.zip")
def run_all(self):
"""执行所有打包步骤"""
print(f"{'='*50}")
print(f"开始打包: {self.project_name} v{self.version}")
print(f"{'='*50}\n")
self.clean()
self.dist_dir.mkdir(exist_ok=True)
# 选择打包方式
if '--exe' in sys.argv:
self.build_exe()
elif '--zip' in sys.argv:
self.create_zip()
else:
self.build_wheel()
print(f"\n{'='*50}")
print(f"打包完成!输出目录: {self.dist_dir}")
print(f"{'='*50}")
# 列出生成的文件
print("\n生成的文件:")
for f in self.dist_dir.iterdir():
size = f.stat().st_size / 1024
print(f" {f.name} ({size:.1f} KB)")
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--name', default='my-automation')
parser.add_argument('--version', default='1.0.0')
args = parser.parse_args()
packager = AutoPackager(args.name, args.version)
packager.run_all()
六、自动化发布到GitHub
使用GitHub Actions自动发布:
# .github/workflows/release.yml
name: Release
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build twine
- name: Build
run: python -m build
- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: twine upload dist/*
七、分发清单
发布前检查清单:
CHECKLIST = [
"代码是否清理了调试信息和测试数据?",
"配置文件是否需要修改(路径、密钥等)?",
"依赖版本是否固定?",
"README.md是否完整?",
"许可证文件是否包含?",
"版本号是否更新?",
"是否在多个环境测试过?",
"打包后是否测试过exe?",
]
总结
打包发布的关键点:
- 小项目:直接分享.py文件或打包成exe
- 可复用项目:打包成wheel发布到PyPI
- 内部工具:打包成exe或zip,使用自动化脚本
- 持续发布:用GitHub Actions实现自动发布
掌握打包技能,让你的自动化脚本能够优雅地分享和部署。
更多推荐



所有评论(0)