ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

解决导包报错:ModuleNotFoundError,ImportError

2021-07-17 17:35:14  阅读:237  来源: 互联网

标签:Python False ImportError py mypackge Base 报错 import ModuleNotFoundError


目录

1. 问题表现

ImportError: attempted relative import with no known parent package
ModuleNotFoundError: No module named 'xxx'

翻译过来大概的意思是:

  1. 找不到父包的情况下进行相对导入
  2. 没有找到xxx模块

2. 尝试去了解

既然找不到父包,那么该如何才能找到它呢?

正如出现上述问题,我个人习惯性直接寻找解决方案,但其实是没深入发掘过,下一次再次遇到了,可能还是知其然不知所以然。

打个比如:某天我正在用浏览器兴致勃勃看着某站视频时,画面突然卡住不动,最先容易想到是不是我的网络断了对吧?

那么这时候,稍微有点网络知识,可能就会去ping一下看看网络状况,进而做下一步诊断。

同样的,在出现上述报错的问题时,使用一个常规方法,即通过sys.path输出的列表,观察Python的环境目录,从而找出错误根源。

3. 先说结论

先说结论:

对于python的应用程序,只需使用绝对路径(不带点哦,如 from .xxx import xxx)一切都会好起来的。

4. 具体问题分析

  • 项目结构和具体程序
"""
├─app
|  ├─mypackge
|	├─module
|      	├─init.py
|       ├─a.py
│       ├─b.py
|       ├─c.py
|  ├─init.py
|  ├─base.py
"""

# base.py
class Base(object):
    print("Base")
    
  
# a.py
from mypackge.base import Base
class A(Base):
    pass


# b.py
from mypackge.base import Base
class B(Base):
    pass


# c.py
from mypackge.base import Base
class C(Base):
    pass

在pycharm中打开上述项目,当我们运行a.py时,一切都很正常,但当我使用command时,python3 a.py,会出现什么问题呢?

出现: ModuleNotFoundError: No module named 'mypackge'

好了,回到最先开始提到的,尝试使用sys.path去发现具体问题,把它放在代码最前面:

import sys
print(sys.path)

# 你的代码

# 当使用pycharm解释器输出:
['C:\\Users\\Rosesx\\Desktop\\app\\mypackge\\module', 'C:\\Users\\Rosesx\\Desktop\\app', 'D:\\Python\\Python39\\python39.zip', 'D:\\Python\\Python39\\DLLs', 'D:\\Python\\Python39\\lib', 'D:\\Python\\Python39', 'D:\\Python\\Python39\\lib\\site-packages', 'D:\\Python\\Python39\\lib\\site-packages\\win32', 'D:\\Python\\Python39\\lib\\site-packages\\win32\\lib', 'D:\\Python\\Python39\\lib\\site-packages\\Pythonwin']

# 当使用command时,python3 a.py,输出:
['C:\\Users\\Rosesx\\Desktop\\app\\mypackge\\module', 'D:\\Python\\Python39\\python39.zip', 'D:\\Python\\Python39\\DLLs', 'D:\\Python\\Python39\\lib', 'D:\\Python\\Python39', 'D:\\Python\\Python39\\lib\\site-packages', 'D:\\Python\\Python39\\lib\\site-packages\\win32', 'D:\\Python\\Python39\\lib\\site-packages\\win32\\lib', 'D:\\Python\\Python39\\lib\\site-packages\\Pythonwin']
Traceback (most recent call last):
  File "C:\Users\Rosesx\Desktop\app\mypackge\module\a.py", line 15, in <module>
    from mypackge.base import Base
ModuleNotFoundError: No module named 'mypackge'

注意观察是不是发现什么?pycharm和command解释器分别输出的内容中,pycharm打印的环境目录列表多了一个项目app绝对路径

是的,无论你把sys.path放到项目中那个.py中去执行,都会看到有一个项目的绝对路径。

直到现在,我猜你似乎已经发现 ModuleNotFoundError问题具体是什么了。

  • 做个测试
# a.py
import sys
from pathlib import Path

for path in sys.path:
    A = Path(path, r'mypackge\base.py') # 遍历python环境目录然后拼接mypackge\base.py
    B = r'C:\Users\Rosesx\Desktop\app\mypackge\base.py' # 预期输入
    if str(A) == B: # 测试一下实际输出结果A和预期输入B
        print(True) 
    else:
        print(False)

from mypackge.base import Base

class A(Base):
    pass

# 当使用pycharm解释器输出:
False
True
False
False
False
False
False
False
False
False
Base

# 当使用command时,python3 a.py,输出:
False
False
False
False
False
False
False
False
False
Traceback (most recent call last):
  File "C:\Users\Rosesx\Desktop\app\mypackge\module\a.py", line 15, in <module>
    from mypackge.base import Base
ModuleNotFoundError: No module named 'mypackge'

经过这么一个小测试,发现使用pycharm解释器输出的实际结果有一条返回True,那么是不是可以说明from mypackge.base import Base成功搜索到它的上级,也就是匹配上了绝对路径。而command输出并没有找到自己的上级而报错。

5. 解决思路

顺着上面得到的验证,当使用command执行python3 a.py时,我们发现它没有导入父模块(也就是说没有找到项目绝对路径)。

这就好办了,在不改动from mypackge.base import Base前提下,加入mypackge的上级目录

# a.py
import sys
from pathlib import Path

sys.path.append(r'C:\Users\Rosesx\Desktop\app') # 加入mypackge的父模块

from mypackge.base import Base

class A(Base):
    pass

也可以这样写:

a.py
import sys
from pathlib import Path

path = Path(__file__).parent.parent.parent  # 链式调用,返回当前a.py的上上上目录
print(path)  # 输出: mypackge上级路径

sys.path.append(str(path))

from mypackge.base import Base


class A(Base):
    pass

6. 总结

是否在看某个库的源代码时,发现它们会使用from ..xxx import xxx 或 from .xxx import xxx导入模块,当我们也这样做的时,就出现导入报错。

.module(带点)是相对导入,相对仅在已先导入或已加载父模块时才有效果,这就意味着你需要在当前运行环境中的某处已导入。当使用command执行python3 module.py,它不会事先导入父模块,你需要自行导入,或者from youproject.moduleA import moduleA这样的方式调用。

不管是怎么写,我们要知道:对于python的应用程序,只需使用绝对路径,一切都会好起来

标签:Python,False,ImportError,py,mypackge,Base,报错,import,ModuleNotFoundError
来源: https://www.cnblogs.com/Rosaany/p/15024170.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有