通过全局包导入本地包

时间:2013-05-05 22:56:48

标签: python-2.6 centos6

我正在为一个大型Python项目开发支持库,该项目通过将各种项目目录附加到sys.path来大量使用相对导入。

使用The Hitchhiker's Guide to Packaging作为模板我尝试创建一个包结构,允许我进行本地安装,但如果需要,可以在以后轻松更改为全局安装。

我的软件包的一个依赖项是pyasn1 package,用于编码和解码ASN.1带注释的对象。我必须单独包含pyasn1库,因为CentOS 6.3默认存储库支持的版本是一个主要版本,并且已知错误会破坏我的自定义包。

库结构的顶层如下:

MyLibrary/
  setup.py
  setup.cfg
  LICENSE.txt
  README.txt
  MyCustomPackage/
  pyasn1-0.1.6/

在我的安装配置文件中,我将库的安装目录定义为名为.lib的本地目录。这是可取的,因为它允许我通过在项目的主应用程序中运行命令import site; site.addsitedir("MyLibrary/.lib")来执行绝对导入,而无需我们的工程师将命令行参数传递给安装脚本。

setup.cfg

[install]
install-lib=.lib

setup.py

setup(                                                                          
   name='MyLibrary',
   version='0.1a',
   package_dir = {'pyasn1': 'pyasn1-0.1.6/pyasn1'},   
   packages=[
             'MyCustomPackage',         
             'pyasn1',
             'pyasn1.codec',
             'pyasn1.compat','
              pyasn1.codec.ber',
             'pyasn1.codec.cer',
             'pyasn1.codec.der',
             'pyasn1.type'
            ],
   license='',
   long_description=open('README.txt').read(),
   data_files = []
)

我以这种方式进行安装时遇到的问题是,当我的包尝试导入pyasn1时,它会导入全局版本并忽略本地安装的版本。

作为一种可行的解决方法,我尝试通过pyasn1以不同于全局包的名称(例如pyasn1_0_1_6)安装package_dir = {'pyasn1_0_1_6':'pyasn1-0.1.6/pyasn1'}包。但是,由于pyasn1包内部使用的导入不使用pyasn1_0_1_6名称,因此失败。

是否有某种方法可以a)强制Python通过全局安装的软件包导入本地安装的软件包,或者b)强制软件包以不同的名称安装?

1 个答案:

答案 0 :(得分:2)

使用virtualenv确保您的应用程序以完全已知的配置运行,该配置独立于操作系统版本的库。

编辑:一个快速(unix)解决方案是设置PYTHONPATH环境变量,它对于Python模块就像PATH一样工作(从找到的第一个路径加载模块,所以只需附加你的目录在PYTHONPATH的开头。 Anwyay,我强烈建议您继续virtualenv ,因为它专门用于处理您所面临的情况。

原理

如果编写setuptools脚本指定与install_requires的依赖关系,则该过程很容易自动化。有关完整示例,请参阅this one I wrote

设置

请注意,您可以在setup.sh shell脚本中轻松插入以下步骤。

首先创建一个virtualenv并输入它:

$ virtualenv $name
$ cd $name

激活它:

$ source bin/activate

现在cd到项目目录并运行安装程序脚本:

$ cd $my_project_dir
$ python ./setup.py --prefix $path_to_virtualenv

注意--prefix $path_to_virtualenv,它用于告诉脚本在virtualenv而不是系统范围内安装。激活virtualenv 后调用此。请注意,所有依赖项都会自动下载并安装在virtualenv中。

然后你就完成了。如果你想离开virtualenv,请发出:

$ deactivate

在后续调用中,您只需要激活virtualenv(步骤2),如果您真的需要,可以使用runawesomeproject.sh

如virtualenv网站上所述,您应该使用virtualenv> = 1.9,因为以前的版本没有通过HTTPS下载依赖项。如果您认为纯HTTP足够,那么任何版本都应该这样做。

您也可以尝试使用可重定位的virtualenvs:设置它并将文件夹复制到您的主机。无论如何,请注意此功能仍然是实验性的