【发布时间】:2013-02-22 14:40:34
【问题描述】:
我需要发送一个 集合 Python 程序,这些程序使用多个 包 存储在本地 Library 目录中:目标是避免让用户在使用之前安装包我的程序(软件包在Library 目录中提供)。导入Library 中包含的包的最佳方法是什么?
我尝试了三种方法,但没有一种是完美的:有没有更简单、更可靠的方法?还是这些方法中的一种是最好的?
-
在第一种方法中,将
Library文件夹简单地添加到库路径中:import sys import os sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'Library')) import package_from_LibraryLibrary文件夹放在开头,以便我的程序附带的软件包优先于用户安装的相同模块(这样我可以确定它们有正确的版本来使用我的程序)。当Library文件夹不在当前目录中时,此方法也有效,这很好。然而,这种方法有缺点。我的每个程序都将相同路径的副本添加到sys.path,这是一种浪费。此外,所有程序都必须包含相同的三个路径修改行,这违反了不要重复自己的原则。 -
对上述问题的改进在于尝试只添加一次
Library路径,方法是在导入的模块中进行:# In module add_Library_path: sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'Library'))然后在我的每个程序中使用:
import add_Library_path import package_from_Library这样,得益于CPython的缓存机制,模块
add_Library_path只运行一次,Library路径只添加到sys.path中一次。然而,这种方法的一个缺点是import add_Library_path有一个不可见的副作用,并且导入的顺序很重要:这使得代码更不清晰,更脆弱。此外,这会迫使我分发的程序包含用户不会使用的add_Library_path.py程序。 -
来自
Library的Python modules 也可以通过将其制成一个包(其中存储有空的
__init__.py文件)来导入,这样可以:from Library import module_from_Library但是,对于
Library中的包,这会中断,因为它们可能会执行类似于from xlutils.filter import …的操作,这会中断,因为xlutils在sys.path中找不到。因此,此方法有效,但仅当在Library中包含模块时才有效。
所有这些方法都有一些缺点。
有没有更好的方法来运送程序,其中包含存储在本地 Library 目录中的一组包(他们使用的)?还是上述方法之一(方法 1?)是最好的方法之一?
PS:在我的例子中,Library 中的所有包都是纯 Python 包,但适用于任何操作系统的更通用的解决方案是最好的。
PPS:目标是用户能够使用我的程序而无需安装任何东西(除了复制我定期发送的目录之外),就像上面的示例一样。
PPPS:更准确地说,我们的目标是通过以下方式灵活地更新我从Library 收集的程序及其相关的第三方包我的用户对包含我的程序和“隐藏”第三方包的Library 文件夹的目录进行简单复制。 (我经常更新,所以我不想强迫用户也更新他们的 Python 发行版。)
【问题讨论】:
-
任何操作系统!
标签: python module package local software-distribution