什么是setup.py,如何配置或使用它?


当前回答

它有助于在您的机器上安装python包foo(也可以在virtualenv中),以便您可以从其他项目以及[I]python提示中导入包foo。

它完成了pip、easy_install等类似的工作。,


使用setup.py

让我们从一些定义开始:

包-包含__init__.py文件的文件夹/目录。模块-扩展名为.py的有效python文件。分发-一个包与其他包和模块的关系。

假设您想安装一个名为foo的包。然后你会,

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

相反,如果你不想实际安装它,但仍然想使用它,

$ python setup.py develop

此命令将在站点包中创建指向源目录的符号链接,而不是复制内容。正因为如此,它的速度相当快(特别是对于大包裹)。


正在创建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中用作包的自述描述。


最后,您现在可以将您的包上传到PyPi.org,以便其他人可以使用pipinstallyourpackage安装您的包。

此时有两种选择。

在临时test.pypi.org服务器上发布以使自己熟悉该过程,然后将其发布在永久pypi.org服务器上,供公众使用您的包。如果您已经熟悉该过程并拥有用户凭据(例如用户名、密码、包名),请立即在永久pypi.org服务器上发布

一旦您的包名在pypi.org中注册,就没有人可以声明或使用它。Python打包建议将twin包用于上传目的(将您的包上传到pypi)。因此

第一步是使用以下方法在本地构建分布:#前提条件:轮子(pip安装轮子)$python setup.py sdist bdist_wheel然后使用twine上传到test.pypi.org或pypi.org:$twine上载--存储库testpypi dist/*用户名:***密码:***

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

$ twine upload dist/*

或者,您也可以通过以下方式使用GPG对包中的文件进行签名:

$ twine upload dist/* --sign

奖金阅读:

在这里查看来自真实项目的示例setup.py:torchvision-setup.pyPEP 517,设置工具为什么缠绕?使用绳线

其他回答

它有助于在您的机器上安装python包foo(也可以在virtualenv中),以便您可以从其他项目以及[I]python提示中导入包foo。

它完成了pip、easy_install等类似的工作。,


使用setup.py

让我们从一些定义开始:

包-包含__init__.py文件的文件夹/目录。模块-扩展名为.py的有效python文件。分发-一个包与其他包和模块的关系。

假设您想安装一个名为foo的包。然后你会,

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

相反,如果你不想实际安装它,但仍然想使用它,

$ python setup.py develop

此命令将在站点包中创建指向源目录的符号链接,而不是复制内容。正因为如此,它的速度相当快(特别是对于大包裹)。


正在创建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中用作包的自述描述。


最后,您现在可以将您的包上传到PyPi.org,以便其他人可以使用pipinstallyourpackage安装您的包。

此时有两种选择。

在临时test.pypi.org服务器上发布以使自己熟悉该过程,然后将其发布在永久pypi.org服务器上,供公众使用您的包。如果您已经熟悉该过程并拥有用户凭据(例如用户名、密码、包名),请立即在永久pypi.org服务器上发布

一旦您的包名在pypi.org中注册,就没有人可以声明或使用它。Python打包建议将twin包用于上传目的(将您的包上传到pypi)。因此

第一步是使用以下方法在本地构建分布:#前提条件:轮子(pip安装轮子)$python setup.py sdist bdist_wheel然后使用twine上传到test.pypi.org或pypi.org:$twine上载--存储库testpypi dist/*用户名:***密码:***

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

$ twine upload dist/*

或者,您也可以通过以下方式使用GPG对包中的文件进行签名:

$ twine upload dist/* --sign

奖金阅读:

在这里查看来自真实项目的示例setup.py:torchvision-setup.pyPEP 517,设置工具为什么缠绕?使用绳线

当您下载带有setup.py的软件包时,请打开终端(Mac、Linux)或命令提示符(Windows)。使用cd并帮助您使用Tab按钮,将路径设置为您下载文件的文件夹和setup.py所在的文件夹:

iMac:~ user $ cd path/pakagefolderwithsetupfile/

按回车键,您将看到如下内容:

iMac:pakagefolderwithsetupfile user$

然后在python setup.py安装之后键入:

iMac:pakagefolderwithsetupfile user$ python setup.py install

按enter键。完成!

setup.py是Python对多平台安装程序和make文件的回答。

如果您熟悉命令行安装,那么make&&makeinstall将转换为python setup.py build&&python setup.py install。

有些包是纯Python的,并且只进行字节编译。其他可能包含本机代码,这将需要本机编译器(如gcc或cl)和Python接口模块(如swig或pyrex)。

为了简单起见,当您调用安装函数时,setup.py会以“__main__”的形式运行,其他答案也会提到。在setup.py中,您应该放置安装软件包所需的一切。

常用setup.py函数

以下两个部分讨论了许多setup.py模块具有的两个功能。

设置工具。设置

此函数允许您指定项目属性,如项目名称、版本。。。。最重要的是,该功能允许您安装其他功能(如果它们打包正确)。有关setuptools.setup的示例,请参见此网页setuptools.setup的这些属性允许安装以下类型的软件包:

使用setuptools.findpackages导入到项目并在PyPI中列出的包:packages=find_packages(exclude=[“docs”,“tests”,”.gitignore“,”README.rst“,”DESCRIPTION.rst“])包不在PyPI中,但可以使用dependency_links从URL下载dependency_links=[“http://peak.telecommunity.com/snapshots/",]

自定义函数

在理想的世界中,setuptools.setup将为您处理一切。不幸的是,情况并非总是如此。有时,您必须执行特定的操作,例如使用subprocess命令安装依赖项,以使正在安装的系统处于适合您的包的正确状态。为了避免这种情况,这些功能会变得混乱,并且在操作系统甚至发行版之间经常会有所不同。

setup.py与其他任何文件一样是一个Python文件。它可以使用任何名称,但按照惯例,它被命名为setup.py,因此每个脚本都没有不同的过程。

最常见的setup.py用于安装Python模块,但用于服务器其他目的:

模块:

也许这是setup.py在模块中最著名的用法。尽管可以使用pip安装它们,但旧的Python版本在默认情况下不包含pip,它们需要单独安装。

如果您想安装模块,但不想安装pip,那么几乎唯一的选择就是从setup.py文件安装模块。这可以通过python setup.py安装实现。这将把Python模块安装到根字典中(没有pip、easy_install等)。

当pip失败时,通常使用此方法。例如,如果所需包的正确Python版本无法通过pip获得,可能是因为它不再被维护,那么下载源代码并运行Python setup.py安装将执行相同的操作,除非需要编译二进制文件(但将忽略Python版本-除非返回错误)。

setup.py的另一个用途是从源代码安装软件包。如果模块仍在开发中,车轮文件将不可用,唯一的安装方法是直接从源代码安装。

构建Python扩展:

构建模块后,可以使用distutils设置脚本将其转换为可供分发的模块。一旦构建完成,就可以使用上面的命令安装它们。

安装脚本很容易构建,一旦正确配置了文件,就可以通过运行pythonsetup.pybuild来编译(请参阅所有命令的链接)。

为了便于使用和惯例,它再次命名为setup.py,但可以使用任何名称。

赛龙:

setup.py文件的另一个著名用法包括编译的扩展名。这需要具有用户定义值的设置脚本。它们允许快速(但一旦编译就依赖于平台)执行。以下是文档中的一个简单示例:

from distutils.core import setup
from Cython.Build import cythonize

setup(
    name = 'Hello world app',
    ext_modules = cythonize("hello.pyx"),
)

这可以通过python setup.py build编译

Cx_冻结:

另一个需要安装脚本的模块是cx_Freeze。这将Python脚本转换为可执行文件。这允许许多命令(如描述、名称、图标、包)包含、排除等,一旦运行就会产生一个可分发的应用程序。文档中的示例:

import sys
from cx_Freeze import setup, Executable
build_exe_options = {"packages": ["os"], "excludes": ["tkinter"]} 

base = None
if sys.platform == "win32":
    base = "Win32GUI"

setup(  name = "guifoo",
        version = "0.1",
        description = "My GUI application!",
        options = {"build_exe": build_exe_options},
        executables = [Executable("guifoo.py", base=base)])

这可以通过python setup.py build进行编译。

那么什么是setup.py文件?

很简单,它是一个在Python环境中构建或配置内容的脚本。

一个包在分发时应该只包含一个安装脚本,但将多个脚本组合成一个安装程序脚本并不罕见。请注意,这通常涉及distutils,但并不总是如此(如我在上一个示例中所示)。需要记住的是,它只是以某种方式配置Python包/脚本。

它采用该名称,因此在构建或安装时始终可以使用相同的命令。