我们可以对python包装和导入如何工作提供一些明确的说明吗?
我有很好的机会通过模块化的Pythonpipe理,每一次都是一个挑战:包装不是人们每天都在做的事情,它成为学习的负担,即使在实际操作时也要记住一个负担,因为这通常发生一次。
我想在这里收集关于python的导入,包pipe理和分发如何工作的明确的概述,以便这个问题成为所有发生在引擎之下的魔法的明确解释。 虽然我理解这个问题的广泛层面,但这些东西是如此交织在一起,以至于任何有针对性的答案都不能解决主要问题:理解所有作品,什么是过时的,什么是当前的,什么是同一个任务的替代品,什么是怪癖。
以下是关键词列表,但这只是一个例子。 还有更多,欢迎您添加更多的细节。
- 的PyPI
- setuptools /分发
- 的distutils
- 蛋
- 鸡蛋链接
- 果仁
- 的zipimport
- site.py
- 站点包
- .pth文件
- 的virtualenv
- 处理鸡蛋中已编译的模块(通过easy_install进行安装和未安装)
- 使用get_data()
- pypm
- 便当
- PEP 376
- 奶酪店
- eggsecutable
链接到其他答案可能是一个好主意。 正如我所说,这个问题是高层次的概述。
在大多数情况下,这是试图看待包装/分销方面,而不是import
。 不幸的是,包装是Python提供多种方法的地方。 我只是想把球打滚,希望别人能帮我填补我想念的或指出的错误。
首先这里有一些杂乱的术语。 包含__init__.py
文件的目录是一个包。 然而,我们这里讨论的大多数是在PyPI上发布的软件包的特定版本,它是其中的一个镜像,或者是像Debian's Apt,Redhat的Yum,Fink,Macports,Homebrew或ActiveState的pypm这样的供应商特定的软件包pipe理系统。
这些发布的软件包是人们试图称之为“发行版”的尝试,只是试图将“软件包”用作Python语言结构。 您可以在PEP-376 PEP-376中看到一些用法。
现在,您的关键字列表与Python生态系统的几个不同方面有关:
查找和发布python发行版:
- PyPI(又名奶酪店)
- PyPI镜像
- 各种包pipe理工具/系统:apt,yum,fink,macports,homebrew
- pypm(ActiveState替代PyPI)
以上所有服务都提供了以各种格式发布Python发行版的地方。 有些像PyPI镜像和apt / yum存储库可以在本地机器上运行,也可以在公司networking中运行,但是人们通常使用官方版本。 大多数(如果不是全部的话)提供一个工具(或PyPI的情况下是多个工具)来帮助查找和下载发行版。
用于创build和安装发行版的库:
-
setuptools
/分发 -
distutils
Distutils是将Python包编译并构build到发行版中的标准基础结构。 distutils
有很多function,但大多数人都知道:
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提供了支持蛋格式及其所有function和弱点所必需的钩子。 分发是Setuptools的一个替代scheme,它增加了一些function,同时试图大部分向后兼容。 我相信Distribute将作为Distutil的from distutils.core import setup
的inheritance者被包含在Python 3中。
Setuptools和Distribute都提供了distutils
setup命令的一个自定义版本,用来支持Egg格式。
Python分发格式:
- 资源
- 蛋
分发通常作为源档案(tarball或zipfile)提供。 安装源代码分发的标准方法是下载并解压缩存档,然后运行setup.py
文件。
例如,下面将下载,构build并安装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
鸡蛋受到Java的Jarfiles的启发,它们有很多你应该阅读的function
Python包格式:
- 未压缩的目录
- zipimport(zip压缩目录)
普通的python包只是一个包含__init__.py
文件和任意数量的附加模块或子包的目录。 只要包含在PYTHONPATH
( sys.path
)中,Python也支持查找和加载* .zip文件中的源代码。
安装Python软件包:
-
easy_install
:原始的蛋安装工具,取决于setuptools
-
pip
:目前最stream行的方式来安装python软件包。 类似于easy_install
但更灵活,并具有一些不错的function,如要求文件,以帮助文件依赖和复制部署。 -
pypm
,apt
,yum
,fink等
环境pipe理/自动化部署:
-
bento
-
buildout
-
virtualenv
(和virtualenvwrapper
)
上述工具用于帮助自动化和pipe理Python项目的依赖关系。 基本上,他们给你工具来描述你的应用程序需要什么发行版,并自动安装这些特定版本的依赖项。
软件包/发行版的位置:
- 站点包
-
PYTHONPATH
- 当前工作目录(取决于您的操作系统和环境设置)
默认情况下,安装一个python发行版将把它放到site-packages目录中。 该目录通常是/usr/lib/pythonX.Y/site-packages
。
一个简单的编程方式来find您的网站包目录:
from distuils import sysconfig print sysconfig.get_python_lib()
如何修改你的PYTHONPATH:
Python的导入语句只能find位于PYTHONPATH
包含的目录之一的包。
您可以通过以下方式检查并更改Python中的path:
import sys print sys.path sys.path.append("/home/myname/lib")
除此之外,您可以像设置OS上的任何其他环境variables一样设置PYTHONPATH
环境variables,或者可以使用:
- .pth文件:* .pth文件位于已经在你的
PYTHONPATH
中的目录中,并且* .pth文件的每一行都被添加到你的PYTHONPATH
。 基本上任何时候你将一个软件包复制到你的PYTHONPATH
目录中,你可以改为创build一个mypackages.pth
。 阅读有关* .pth文件的更多信息: 站点模块 - 蛋链接文件: 蟒蛋的内部结构,它们是一个跨平台的替代符号链接。 创build一个蛋链接文件类似于创build一个pth文件。
-
site.py
修改
要将上面的/home/myname/lib
到带* .pth文件的网站包中,您将创build一个* .pth文件。 文件的名字并不重要,但是你应该select一些合理的东西。
让我们创buildmyname.pth
:
# myname.pth /home/myname/lib
而已。 把它放到你的系统上的sysconfig.get_python_lib()
,或者把你的PYTHONPATH
和/home/myname/lib
其他目录join到path中。
对于打包问题,这应该有助于http://guide.python-distribute.org/
对于import,来自Fredrik Lundh的旧文章http://effbot.org/zone/import-confusion.htm仍然是一个很好的起点。;
我推荐Tarek Ziadek的Python书。 有一章致力于包装和分销。
我不认为import
需要探索(Python的命名空间和导入function是直观的恕我直言)。
我现在只用pip
。 我没有遇到任何问题。
但是,包装和分销这个话题是值得探讨的。 我会这样说,而不是给出一个冗长的答案:
我学会了如何打包和分发我自己的“软件包”,只需简单地复制Pylons或许多其他开源软件包的function。 然后,我将这种模板与阅读文档结合起来,进一步充实,并提出了一个可靠的分发方法。
当你为python(distutils和pypi)打包pipe理和分发时,它实际上是非常强大的。 我很喜欢。
[编辑]
我也想补充一下virtualenv。 用它。 我为每个项目创build了一个virtualenv,我总是使用--no-site-packages
; 我在virtualev里安装了我所需要的特定项目的所有软件包(即使它们之间有一些共同点,比如lxml
)。 它使所有事情都保持孤立,对我来说维护头脑更容易(而不是试图跟踪什么地方,哪个版本的Python!)
[/编辑]