在Python中导入嵌套模块

1 投票
1 回答
4897 浏览
提问于 2025-04-16 05:27

我正在尝试将一些库导入到我的程序中(这是一个谷歌的AppEngine应用)。基本上,我应该把所有的库放在根文件夹里,但我新建了一个叫lib的文件夹,把它们放在里面。(我还创建了一个__init__.py文件)

正常情况下,我可以通过import lib.module或者from lib import module来导入库,没问题。但是当我尝试导入一个完整的包,比如一个叫pack1的文件夹,里面有多个模块时,我用from lib.pack1 import *来导入,就会在其中一个模块中出现错误,因为这个模块静态地访问了另一个模块,也就是from pack1.mod2 import sth
有没有简单又干净的方法来解决这个问题?而且不想修改库本身。

编辑:我使用的是Python 2.7。
编辑:错误信息:当我使用import lib.pack1时,出现ImportError: No module named pack1.mod1

1 个回答

6

我觉得你其实应该用 from lib.pack1.mod2,而不是 from pack1.mod2

编辑:另外,告诉我你用的是什么版本的Python会很有帮助,因为导入的规则这些年逐渐改进了!

编辑:哦!谢谢你的评论,我现在明白了。你是想在不进入库的情况下重命名它们,因为它们的名字现在不同了。问题是,你这样做是不可能的。如果所有库内部都使用相对导入,那你可能有机会做到;但是,相对导入(a)是最近才出现的,并且(b)并没有被广泛使用。

所以,如果你想使用库 p,你必须把它放在你的根目录下,而不是放在 lib/p 里面,因为那样会创建一个不同名字的库:lib.p,这会让库感到很意外,并导致它出错。

不过我还有两个想法。

首先,如果你这样做是为了整理文件,而不是因为你需要不同的导入名称,那么(a)像你现在这样创建 lib 是可以的,但(b)不要在里面放一个 __init__.py!相反,把 lib 目录添加到你的 PYTHONPATH 中,或者在你的程序里添加到 sys.path。 (GAE 允许你这样做吗?它有 PYTHONPATH 吗?)

第二,我说这不可能其实有点不准确。严格来说,你可以通过在 sys.metapath 中添加一个条目来实现,这样可以拦截所有模块查找,并尝试从 lib 中获取它们,如果它们在那里存在。但——这听起来很麻烦。

撰写回答