Python文件夹与模块同名时,直接import失败但from...import...成功的原因
问题原因解析
核心原因是:当你的工作目录是一个与目标模块同名的文件夹时,Python的导入机制会优先将该文件夹识别为「包」,而非加载同名的.py模块文件。
具体细节拆解:
import my_module失败的逻辑
当你执行os.chdir("~/my_module")后,当前工作目录被设为这个名为my_module的文件夹。此时执行import my_module,Python会按sys.path的搜索顺序(当前目录优先级最高)进行查找:- 首先检查当前目录下是否存在名为
my_module的文件夹(即包),发现存在后,会直接将这个文件夹作为一个包导入,完全跳过了对同名.py文件的查找。 - 由于这个文件夹没有
__init__.py文件,它属于Python 3.3+支持的命名空间包,这类包不会自动导入内部的模块。所以你以为导入了自己写的my_module.py,实际上只是导入了一个空的命名空间包,自然无法使用模块内的功能,表现为“导入失败”。
- 首先检查当前目录下是否存在名为
from my_module import my_module成功的逻辑
这个语法的作用是:从名为my_module的包(即当前目录下的同名文件夹)中,导入名为my_module的模块。此时Python会进入该包的目录内部查找,成功定位到my_module.py文件并完成导入,因此能正常使用模块功能。修改文件夹名后正常的逻辑
当你把文件夹名改为与模块名不同(比如my_module_dir),当前目录下不再存在名为my_module的文件夹。此时执行import my_module,Python会直接查找当前目录下的my_module.py文件,自然能正常导入模块。
验证小技巧
你可以通过以下代码直观看到差异:
import os os.chdir(os.path.expanduser("~/my_module")) import my_module print(type(my_module)) # 输出 <class 'module'>,但这是命名空间包,不是你的.py模块 print(my_module.__file__) # 会抛出 AttributeError,因为命名空间包没有__file__属性 # 对比成功导入的情况 from my_module import my_module as my_real_module print(type(my_real_module)) # 输出 <class 'module'> print(my_real_module.__file__) # 输出你的my_module.py文件路径
内容的提问来源于stack exchange,提问作者ginjaemocoes
相关产品推荐
相关产品推荐

