什么是setup.py?

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

974149 次浏览

setup.py是一个python文件,它的存在表明您将要安装的模块/包可能已经用发行Python模块的标准——Distutils打包和分发。

这使您可以轻松安装Python包。通常只需编写:

$ pip install .

pip将使用setup.py安装您的模块。避免直接调用setup.py

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

如果您下载的软件包在根文件夹中有“setup.py”,您可以通过运行

python setup.py install

如果您正在开发一个项目并且想知道这个文件有什么用,请检查Python留档编写安装脚本

setup.py是一个Python脚本,通常随库或程序一起提供,用该语言编写。它的目的是正确安装软件。

许多包使用distutils框架与setup.py结合使用。

http://docs.python.org/distutils/

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

如果您熟悉命令行安装,则make && make install转换为python setup.py build && python setup.py install

有些包是纯Python的,只有字节编译。其他人可能包含本机代码,这需要本机编译器(如gcccl)和Python接口模块(如swigpyrex)。

setup.py可以用于两种情况,首先,你想安装一个Python包。其次,你想创建自己的Python包。通常标准的Python包有几个重要的文件,如setup.py,setup.cfg和Manifest.in.当你创建Python包时,这三个文件将确定(在Eg-info文件夹下的PKG-INFO中的内容)名称,版本,描述,其他所需的安装(通常在. txt文件中)和一些其他参数。setup.cfg由setup.py在创建包时读取(可能tar.gz)。Manifest.in是您可以定义包中应该包含的内容的地方。无论如何,您可以使用setup.py

python setup.py buildpython setup.py installpython setup.py sdist <distname> upload [-r urltorepo]  (to upload package to pypi or local repo)

还有一堆其他命令可以与setup.py一起使用。寻求帮助

python setup.py --help-commands

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

iMac:~ user $ cd path/pakagefolderwithsetupfile/

按回车键,您应该会看到这样的内容:

iMac:pakagefolderwithsetupfile user$

然后在这个python setup.py install之后键入:

iMac:pakagefolderwithsetupfile user$ python setup.py install

按下enter。完成!

要安装您下载的Python包,您可以提取存档并在其中运行setup.py脚本:

python setup.py install

对我来说,这一直感觉很奇怪。将包管理器指向下载会更自然,就像在Ruby和Nodejs中一样,例如。gem install rails-4.1.1.gem

包管理器也更舒服,因为它熟悉且可靠。另一方面,每个setup.py都是新颖的,因为它是特定于包的。它要求对惯例的信心“我相信这个setup.py接受与我过去使用的其他人相同的命令”。这是对精神意志力的遗憾征税。

我不是说setup.py工作流比包管理器更不安全(我知道Pip只是在里面运行setup.py),但我肯定觉得这很尴尬和不和谐。所有命令都指向同一个包管理器应用程序。你甚至可能会喜欢它。

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

它做类似于pipeasy_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

然后,您在#0脚本中执行以下操作,以便它可以安装在某些机器上:

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 nameinstall_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

然后,你的#0在这种情况下会像:

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 nameinstall_requires=['wheel', 'bar', 'greek'], #external packages as dependenciesscripts=['scripts/cool','scripts/skype',])

添加更多内容到(#0)让它体面:

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 nameinstall_requires=['wheel', 'bar', 'greek'], #external packages as dependenciesscripts=['scripts/cool','scripts/skype',])

long_descriptionpypi.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

阅读奖励

为了简单起见,当您调用安装功能时,setup.py作为"__main__"运行。在setup.py内,您应该放置安装软件包所需的一切。

共同setup.py功能

以下两节讨论许多setup.py模块具有的两件事。

setuptools.setup

此函数允许您指定项目属性,例如项目名称、版本……最重要的是,此函数允许您安装打包正确的其他函数。有关setuptools.setup的示例,请参阅此网页

setuptools.setup的这些属性允许安装这些类型的包:

  • 导入到您的项目并在PyPI中使用setuptools.findpackages列出的包:

    packages=find_packages(exclude=["docs","tests", ".gitignore", "README.rst","DESCRIPTION.rst"])

  • 包不在PyPI中,但可以使用dependency_links从URL下载

    dependency_links=["http://peak.telecommunity.com/snapshots/",]

自定义函数

在一个理想的世界里,setuptools.setup会为你处理一切。不幸的是,情况并非总是如此。有时你必须做一些特定的事情,比如使用子进程命令安装依赖项,以使你正在安装的系统处于适合你的包的正确状态。尽量避免这种情况,这些功能会令人困惑,并且经常在os甚至分布之间有所不同。

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

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

模块:

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

如果你想安装一个模块但不想安装pip,唯一的选择是从setup.py文件安装模块。这可以通过python setup.py install实现。这将把Python模块安装到根字典(没有pipeasy_install等)。

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

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

构建Python扩展:

构建模块后,可以使用distutils设置脚本将其转换为准备分发的模块。构建后,可以使用上面的命令安装这些。

安装脚本很容易构建,一旦文件被正确配置,就可以通过运行python setup.py build进行编译(有关所有命令,请参阅链接)。

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

Cython:

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

from distutils.core import setupfrom Cython.Build import cythonize
setup(name = 'Hello world app',ext_modules = cythonize("hello.pyx"),)

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

Cx_Freeze:

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

import sysfrom cx_Freeze import setup, Executablebuild_exe_options = {"packages": ["os"], "excludes": ["tkinter"]}
base = Noneif 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包/脚本。

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