什么是setup.py文件

什么是setup.py文件

技术背景

setup.py 是一个 Python 文件,它的存在表明你要安装的模块或包可能已使用 Distutils 进行打包和分发,Distutils 是 Python 模块分发的标准。它能让你轻松安装 Python 包,在过去 Python 版本未默认包含 pip 时,setup.py 是安装模块的重要方式。

实现步骤

使用 setup.py 安装包

  1. 克隆项目仓库:
1
2
$ git clone https://github.com/user/foo
$ cd foo
  1. 安装包:
1
$ python setup.py install

若不想实际安装,只是使用,可以执行:

1
$ python setup.py develop

创建 setup.py 文件

简单包结构

若包结构如下:

1
2
3
4
5
6
7
8
foo
├── foo
│ ├── data_struct.py
│ ├── __init__.py
│ └── internals.py
├── README
├── requirements.txt
└── setup.py

setup.py 内容如下:

1
2
3
4
5
6
7
8
9
10
11
from setuptools import setup

setup(
name='foo',
version='1.0',
description='A useful module',
author='Man Foo',
author_email='[email protected]',
packages=['foo'], # same as name
install_requires=['wheel', 'bar', 'greek'], # external packages as dependencies
)

复杂包结构

若包结构如下:

1
2
3
4
5
6
7
8
9
10
11
foo
├── foo
│ ├── data_struct.py
│ ├── __init__.py
│ └── internals.py
├── README
├── requirements.txt
├── scripts
│ ├── cool
│ └── skype
└── setup.py

setup.py 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from setuptools import setup

setup(
name='foo',
version='1.0',
description='A useful module',
author='Man Foo',
author_email='[email protected]',
packages=['foo'], # same as name
install_requires=['wheel', 'bar', 'greek'], # external packages as dependencies
scripts=[
'scripts/cool',
'scripts/skype',
]
)

添加更多信息到 setup.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from setuptools import setup

with open("README", 'r') as f:
long_description = f.read()

setup(
name='foo',
version='1.0',
description='A useful module',
license="MIT",
long_description=long_description,
author='Man Foo',
author_email='[email protected]',
url="http://www.foopackage.example/",
packages=['foo'], # same as name
install_requires=['wheel', 'bar', 'greek'], # external packages as dependencies
scripts=[
'scripts/cool',
'scripts/skype',
]
)

上传包到 PyPi

  1. 本地构建发行版:
1
2
# 前提:安装 wheel (pip install wheel)
$ python setup.py sdist bdist_wheel
  1. 使用 twine 上传到 test.pypi.orgpypi.org
1
2
3
$ twine upload --repository testpypi dist/*
username: ***
password: ***

若满意测试结果,可上传到正式的 pypi.org

1
$ twine upload dist/*

可选,使用 GPG 对包文件签名:

1
$ twine upload dist/* --sign

核心代码

常见 setup.py 函数

setuptools.setup

1
2
3
4
5
6
7
8
9
10
11
12
from setuptools import setup, find_packages

setup(
name='your_package_name',
version='1.0.0',
description='Your package description',
author='Your Name',
author_email='[email protected]',
packages=find_packages(exclude=["docs", "tests"]),
install_requires=['dependency1', 'dependency2'],
dependency_links=["http://peak.telecommunity.com/snapshots/"]
)

自定义函数示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import subprocess
from setuptools import setup

def install_dependencies():
subprocess.call(['pip', 'install', 'dependency'])

setup(
name='your_package_name',
version='1.0.0',
description='Your package description',
author='Your Name',
author_email='[email protected]',
# ...
)

install_dependencies()

最佳实践

  • 遵循 setup.py 的命名约定,方便统一操作。
  • 使用 setuptools 而不是 distutils,因为 setuptools 功能更强大。
  • setup.py 中添加详细的 long_description,用于在 PyPi 上展示。
  • 使用 twine 上传包到 PyPi,确保安全。

常见问题

  • 旧版本 Python 没有 pip:可使用 python setup.py install 安装模块。
  • pip 安装失败:可能是所需包的正确 Python 版本不可用,可下载源码并运行 python setup.py install,但可能会忽略 Python 版本。
  • 包结构复杂:正确配置 packagesscripts 参数,确保所有文件被正确包含。