我正在为一个开源闪存卡程序Anki开发一系列附加组件.Anki附加组件作为Python包提供,基本文件夹结构如下所示:
anki_addons/
addon_name_1/
__init__.py
addon_name_2/
__init__.py
Run Code Online (Sandbox Code Playgroud)
anki_addons
sys.path
由基础应用程序附加,然后基本应用程序导入每个add_on import <addon_name>
.
我一直试图解决的问题是找到一种可靠的方法来发送包及其依赖项与我的附加组件,同时不污染全局状态或回退到销售包的手动编辑.
具体来说,给定这样的附加结构......
addon_name_1/
__init__.py
_vendor/
__init__.py
library1
library2
dependency_of_library2
...
Run Code Online (Sandbox Code Playgroud)
...我希望能够导入_vendor
目录中包含的任意包,例如:
from ._vendor import library1
Run Code Online (Sandbox Code Playgroud)
像这样的相对导入的主要困难是它们不适用于也依赖于通过绝对引用导入的其他包的包(例如import dependency_of_library2
,在源代码中library2
)
到目前为止,我已经探索了以下选项:
import addon_name_1._vendor.dependency_of_library2
).但这是繁琐的工作,不能扩展到更大的依赖树,也不能移植到其他包._vendor
到sys.path
via sys.path.insert(1, <path_to_vendor_dir>)
.这有效,但它引入了对模块查找路径的全局更改,这将影响其他加载项甚至基本应用程序本身.它看起来像是一个黑客,可能会导致后来的潘多拉盒子问题(例如同一个包的不同版本之间的冲突等).我已经被困在这几个小时了,我开始认为我要么完全错过了一个简单的方法,要么我的整个方法存在根本性的错误.
我是否无法使用我的代码发送第三方软件包的依赖关系树,而无需诉诸sys.path
黑客或修改有问题的软件包?
编辑:
只是为了澄清:我无法控制从anki_addons文件夹导入加载项的方式.anki_addons只是基本应用程序提供的目录,其中安装了所有加载项.它被添加到sys路径中,因此其中的附加软件包几乎就像Python的模块查找路径中的任何其他python包一样.