python - 我们能否明确说明 python 打包和导入的工作原理?

标签 python packaging

我有公平的机会通过 Python 管理模块,每次都是一个挑战:打包不是人们每天都做的事情,它成为学习的负担,记住的负担,即使你真的这样做了,因为这通常会发生一次。

我想在这里收集有关 Python 中导入、包管理和分发如何工作的最终概述,以便这个问题成为对幕后发生的所有魔法的最终解释。虽然我理解这个问题的广泛层面,但这些东西是如此交织在一起,以至于任何有针对性的答案都无法解决主要问题:了解所有的工作原理,什么是过时的,什么是最新的,对于同一任务来说,什么只是替代品,什么是怪癖。

要引用的关键字列表如下,但这只是其中的一个示例。还有很多,欢迎您添加其他详细信息。

  • PyPI
  • 设置工具/分发
  • distutils
  • 鸡蛋
  • 蛋联
  • 点子
  • zipimport
  • 网站.py
  • 网站包
  • .pth 文件
  • virtualenv
  • 处理鸡蛋中编译的模块(通过easy_install安装和不安装)
  • 使用 get_data()
  • pypm
  • bento
  • PEP 376
  • 奶酪店
  • Eggsecutable

  • 链接到其他答案可能是一个好主意。正如我所说,这个问题是针对高级别概述的。

    最佳答案

    在大多数情况下,这是尝试着眼于包装/分销方面,而不是 import 的机制。 .不幸的是,打包是 Python 提供不止一种方法的地方。我只是想让球滚动,希望其他人能帮助填补我遗漏的内容或指出错误。

    首先,这里有一些困惑的术语。包含 __init__.py 的目录文件是一个包。然而,我们在这里讨论的大部分内容都是在 PyPI 上发布的特定版本的软件包、它的镜像之一,或者在特定于供应商的软件包管理系统中,如 Debian 的 Apt、Redhat 的 Yum、Fink、Macports、Homebrew 或 ActiveState 的 pypm。

    人们试图将这些已发布的包称为“分发版”,以尝试将“包”仅用作 Python 语言结构。您可以在 PEP-376 中看到其中的一些用法。 PEP-376 .

    现在,您的关键字列表与 Python 生态系统的几个不同方面相关:

    查找和发布 python 发行版:

  • PyPI(又名奶酪店)
  • PyPI 镜像
  • 各种包管理工具/系统:apt、yum、fink、macports、homebrew
  • pypm(ActiveState 替代 PyPI)

  • 以上都是提供以各种格式发布 Python 发行版的地方的所有服务。一些,如 PyPI 镜像和 apt/yum 存储库可以在您的本地机器或您公司的网络中运行,但人们通常使用官方的。大多数(如果不是全部)都提供一个工具(或在 PyPI 的情况下提供多个工具)来帮助查找和下载发行版。

    用于创建和安装发行版的库:
  • setuptools/分发
  • distutils

  • Distutils 是 Python 包编译和构建到发行版中的标准基础设施。 distutils 中有很多功能但大多数人只知道:
    from distutils.core import setup
    
    setup(name='Distutils',
          version='1.0',
          description='Python Distribution Utilities',
          author='Greg Ward',
          author_email='gward@python.net',
          url='http://www.python.org/sigs/distutils-sig/',
          packages=['distutils', 'distutils.command'],
     )
    

    在某种程度上,这是您所需要的大部分内容。使用前面的 9 行代码,您有足够的信息来安装纯 Python 包,以及在 PyPI 上发布该包所需的最少元数据。

    Setuptools 提供了支持 Egg 格式及其所有功能和弱点所需的钩子(Hook)。 Distribute 是 Setuptools 的替代方案,它在尝试向后兼容的同时增加了一些功能。我相信 Distribute 将作为 Distutil 的 from distutils.core import setup 的继承者包含在 Python 3 中。 .

    Setuptools 和 Distribute 都提供了 distutils 的自定义版本。设置命令
    这会做一些有用的事情,比如支持 Egg 格式。

    Python 分发格式:
  • 来源
  • eggs

  • 发行版通常以源文件(tarball 或 zipfile)的形式提供。安装源发行版的标准方法是下载并解压缩文件,然后运行 ​​setup.py里面的文件。

    例如,以下将下载、构建和安装 Pygments 语法高亮库:
    curl -O -G http://pypi.python.org/packages/source/P/Pygments/Pygments-1.4.tar.gz
    tar -zxvf Pygments-1.4.tar.gz
    cd Pygments-1.4
    python setup.py build
    sudo python setup.py install
    

    或者,您可以下载 Egg 文件并安装它。通常这是通过使用 easy_install 或 pip 来完成的:
    sudo easy_install pygments
    or 
    sudo pip install pygments
    

    Eggs受到 Java 的 Jarfiles 的启发,它们有很多你应该阅读的特性 here

    Python 包格式:
  • 未压缩目录
  • zipimport(压缩压缩目录)

  • 一个普通的python 包只是一个包含__init__.py 的目录。文件和任意数量的附加模块或子包。 Python 还支持在 *.zip 文件中查找和加载源代码,只要它们包含在 PYTHONPATH 中即可。 ( sys.path )。

    安装 Python 包:
  • easy_install : 原版egg安装工具,依赖setuptools
  • pip :目前最流行的安装python包的方式。类似于 easy_install但更灵活,并有一些不错的功能,如需求文件,以帮助记录依赖关系和重现部署。
  • pypm , apt , yum 、芬克等

  • 环境管理/自动化部署:
  • bento
  • buildout
  • virtualenv (和 virtualenvwrapper)

  • 上述工具用于帮助自动化和管理 Python 项目的依赖项。基本上,它们为您提供工具来描述您的应用程序需要哪些发行版,并自动安装这些特定版本的依赖项。

    包/分发包的位置:
  • 网站包
  • PYTHONPATH
  • 当前工作目录(取决于您的操作系统和环境设置)

  • 默认情况下,安装 python 发行版会将其放入 site-packages 目录。该目录通常类似于 /usr/lib/pythonX.Y/site-packages .

    一种查找站点包目录的简单编程方法:
    from distuils import sysconfig
    print sysconfig.get_python_lib()
    

    修改 PYTHONPATH 的方法:

    Python 的 import 语句只会查找位于 PYTHONPATH 中包含的目录之一中的包。 .

    您可以通过访问以下内容从 Python 中检查和更改您的路径:
    import sys
    print sys.path
    sys.path.append("/home/myname/lib")
    

    除此之外,您还可以设置PYTHONPATH环境变量就像您操作系统上的任何其他环境变量一样,或者您可以使用:
  • .pth 文件:*.pth 文件位于 PYTHONPATH 上的目录中读取并将 *.pth 文件的每一行添加到您的 PYTHONPATH .基本上任何时候您将一个包复制到您的 PYTHONPATH 上的目录中。你可以创建一个 mypackages.pth .阅读有关 *.pth 文件的更多信息:site module
  • 蛋链接文件:Internal structure of python eggs它们是符号链接(symbolic link)的跨平台替代品。创建 egg 链接文件类似于创建 pth 文件。
  • site.py修改

  • 添加以上/home/myname/lib到带有 *.pth 文件的站点包,您将创建一个 *.pth 文件。文件的名称无关紧要,但您仍然应该选择合理的名称。

    让我们创建 myname.pth :
    # myname.pth
    /home/myname/lib
    

    就是这样。将其放入 sysconfig.get_python_lib()在您的系统或您的 PYTHONPATH 中的任何其他目录中和 /home/myname/lib将被添加到路径中。

    关于python - 我们能否明确说明 python 打包和导入的工作原理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5714916/

    相关文章:

    .net - 如何创建支持多平台的 nuget 包

    java - maven - 两个不同的根 pom

    python - 使用piprequirements.txt更新下游项目的依赖关系

    python - 使用聚类从文档列表中找出所有潜在的相似文档

    Python - 无法检测面部和眼睛?

    python - 带有 Selenium 的 Firefox( headless )

    ruby - Ocra 在打包脚本时抛出错误

    python - "from builtins import *"和 python2 中的 super() : bad practice?

    python - 如何使用 IAM Auth 将 python websocket 连接到 AppSync 订阅?