导入与系统模块同名的模块

3 投票
2 回答
3224 浏览
提问于 2025-04-16 23:52

我的情况和这个问题有点类似……不过有一点不同。

在我们的python/django项目中,有一个叫utils的文件夹,里面放着一些基本的函数……

有时候,我们需要通过控制台运行一些模块来测试,比如这样:

python myproject/some_module.py

一切都很好,直到python尝试从我们的 utils 文件夹中导入东西……

from utils.custom_modules import some_function
ImportError: No module named custom_modules

我检查了我的python路径,我们的项目在列表中,每个项目文件夹下都有__init__.py文件,当我在项目目录下运行ipython时……一切正常,否则,python就会从它自己的utils文件夹中导入……

我的同事们用同样的方法没有任何问题,但在我的环境中却出现了ImportError错误……我们大家都忽略了什么问题呢?

更新:我的项目目录和每个子目录都有__init__.py文件,我可以毫无问题地从我的项目中导入其他模块……当我在不同于我的项目的文件夹中运行ipython时,导入没有问题……

from someothermodule.submodule imprort blahblahblah

但是,当涉及到导入utils时,就失败了……

更新2:问题的原因是django文件夹下的utils目录,它也在python路径中……

2 个回答

-1

我就不啰嗦了,直接说吧,尽量不要把自己写的模块名字和标准库的模块名字搞混。

如果你想保持这个名字不变,那么在每个引用你自己工具模块的地方,都得用类似下面的写法:

import sys, imp

utils = sys.modules.get('utils')
if not utils: utils = imp.load_module('utils',*imp.find_module('utils/utils'))

不过,如果你改名字后需要修改的地方不多,我建议你还是改一下名字比较好。

6

请查看关于绝对导入和相对导入的PEP文档,里面有详细的解释。你可能想要这样做:

from .utils.custom_modules import some_function

如果你在一个包的顶层文件中。

补充说明:这只能在包内部进行。这是有原因的——如果你正在导入项目中的某个东西,那你实际上已经把它当作一个Python包来使用了,所以你应该真正把它做成一个包。你可以通过在项目目录中添加一个__init__.py文件来实现。

补充说明2:你已经完全改变了问题的方向。虽然可能有办法绕过这个问题,但正确的做法是不要把你的包和内置包用同样的方式来引用。你要么需要重命名utils,要么把它做成另一个包的子包,这样你就可以用一个不冲突的名字来引用它(比如from mydjangoapp.utils.custom_modules import some_function)。

撰写回答