什么是setup.py?

1588 投票
10 回答
1145078 浏览
提问于 2025-04-15 14:34

setup.py 是一个用来帮助你设置和安装Python项目的文件。简单来说,它就像是一个说明书,告诉计算机如何处理你的代码。

在这个文件里,你可以写一些配置,比如项目的名字、版本、作者信息,以及需要哪些额外的库来让你的项目正常运行。这样,当别人想要使用你的项目时,他们只需要运行这个文件,计算机就会自动帮他们安装好所有需要的东西。

总之,setup.py 让分享和安装Python项目变得更加简单方便。

10 个回答

131

setup.py 是 Python 用来创建跨平台安装程序的工具,类似于其他编程语言中的 make 文件。

如果你对命令行安装有一些了解,那么 make && make install 可以理解为 python setup.py build && python setup.py install

有些软件包是纯 Python 编写的,只需要进行字节编译。而有些软件包可能包含本地代码,这就需要用到本地编译器(比如 gcccl)和一些 Python 接口模块(比如 swigpyrex)。

803

在你的电脑上安装一个叫做 foo 的 Python 包是很有帮助的(也可以在 virtualenv 中安装),这样你就可以在其他项目中以及在 [I]Python 提示符下导入这个包 foo

它的功能和 pipeasy_install 等类似。


使用 setup.py

我们先来定义一些概念:

- 一个包含 __init__.py 文件的文件夹/目录。
模块 - 一个有效的 Python 文件,后缀为 .py
分发 - 一个 和其他 模块 之间的关系。

假设你想安装一个名为 foo 的包。你可以这样做:

$ git clone https://github.com/user/foo
$ cd foo
$ python setup.py install

如果你不想真正安装它,但仍然想使用它,可以这样做:

$ python setup.py develop

这个命令会在 site-packages 目录下创建指向源目录的符号链接,而不是复制文件。这样做速度很快,尤其是对于大型包。


创建 setup.py

如果你的包结构是这样的:

foo
├── foo
│   ├── data_struct.py
│   ├── __init__.py
│   └── internals.py
├── README
├── requirements.txt
└── setup.py

那么,在你的 setup.py 脚本中,你可以这样做,以便在某台机器上安装:

from setuptools import setup

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

如果你的包结构更复杂,如下所示:

foo
├── foo
│   ├── data_struct.py
│   ├── __init__.py
│   └── internals.py
├── README
├── requirements.txt
├── scripts
│   ├── cool
│   └── skype
└── setup.py

那么,在这种情况下,你的 setup.py 应该是这样的:

from setuptools import setup

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

setup.py 中添加更多内容 & 让它看起来不错:

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='foomail@foo.example',
   url="http://www.foopackage.example/",
   packages=['foo'],  #same as name
   install_requires=['wheel', 'bar', 'greek'], #external packages as dependencies
   scripts=[
            'scripts/cool',
            'scripts/skype',
           ]
)

long_description 用于在 pypi.org 上作为你包的 README 描述。


最后,你现在可以将你的包上传到 PyPi.org,这样其他人就可以通过 pip install yourpackage 来安装你的包。

此时有两个选择:

  • 临时的 test.pypi.org 服务器上发布,以便熟悉流程,然后再在 永久的 pypi.org 服务器上发布,让公众使用你的包。
  • 如果你已经熟悉流程并且有用户凭证(例如用户名、密码、包名),可以直接在 永久的 pypi.org 服务器上发布。

一旦你的包名在 pypi.org 注册,没人可以声称或使用它。Python 打包建议使用 twine 包来上传你的包到 PyPi。 因此,

  1. 第一步是在本地 构建 分发包,使用:

    # prereq: wheel (pip install wheel)
    $ python setup.py sdist bdist_wheel
    
  2. 然后使用 twine 上传到 test.pypi.orgpypi.org

    $ twine upload --repository testpypi dist/*
    username: ***
    password: ***
    

包在 test.pypi.org 上出现需要几分钟。一旦你满意,就可以简单地将包上传到 pypi.org 的真实和永久索引:

$ twine upload dist/*

可选地,你还可以通过 GPG 签署你的包中的文件,方法是:

$ twine upload dist/* --sign

额外阅读

1176

setup.py 是一个 Python 文件,它的存在意味着你要安装的模块或包很可能是通过 Distutils 打包和分发的。Distutils 是分发 Python 模块的标准工具。

有了这个文件,你可以很方便地安装 Python 包。通常只需要写:

$ pip install . 

pip 会使用 setup.py 来安装你的模块。尽量避免直接调用 setup.py

https://docs.python.org/3/installing/index.html#installing-index

撰写回答