python常见错误:No Module named xxx

1,问题描述

python开发过程中,非常常见的一种错误。对于初学者常常比较困惑,希望有一个排查该类问题的套路过程。其实对于经验丰富的python开发工程师写出的程序,也可能会出现该类错误。

2,原因

这种提示是指python解释器在解释import语句时,找不到对应的模块,具体原因如下:

  • python通过模块来组织代码。
  • 模块就是python文件夹(有__init__.py文件的文件夹),python文件,python类(python里一切皆类)。
  • import语句可实现不同模块之间引用。
  • 引用是按照某个搜索顺序,依次查找一些路径(就是操作系统的磁盘目录)。
  • 这个搜索顺序是通过 sys.path 来确定的。
  • 如果所有路径都无法正常找到,就提示No Module named xxx。

3,如何解决

上面那一章节都是废话,下面直接给出排查和解决套路。

3.1 xxx是一个三方包

3.1.1 三方包没有安装

解决步骤:看下有没有安装这个三方包,没有就安装一下。

# 查询是否安装了某个三方包,以tornado这个三方包为例

duyabodeMacBook-Pro:~ duyabo$ pip list |grep tornado

DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.

tornado 4.3

duyabodeMacBook-Pro:~ duyabo$ pip install tornado==4.3 # 如果没有就安装一下 pip install xxx=version

3.1.2 三方包已经安装过了

解决步骤:

  • 看下解释器是否正确。一台机器上,可能有python2,python3,是否python2安装了三方包,但是python3没有安装。
  • 看下是否使用了虚拟环境。python为了环境隔离,有时候会使用venv。有可能主机环境安装了三方包,但是项目使用的虚拟环境并没有安装。
  • 看下是否安装了错误的三方包。有些时候三方包的名字,由于历史原因和代码引用的名字并不一样(比如代码里 import pymysql,但是事实上三方包对应名字PyMySQL)。

3.1.3 代码修改了sys.path

解决步骤:比较极端,有新手在代码里修改了sys.path,比如删除了/Library/Python/2.7/site-packages,即使安装了三方包,也正常选择了解释器,但是仍然找不到这个模块。使用默认的sys.path一般是没有问题的。

3.2 xxx是本地模块

3.2.1 sys.path 问题

通常是执行脚本的sh命令,所在的目录不对。因为python解释器会自动把命令执行的工作目录添加到sys.path中。

解决步骤:更换执行命令的工作目录,或者手动修改脚本文件的sys.path。

3.2.2 非法模块问题

  • python目录没有__init__.py文件。新建一下。
  • 远程执行时,上传的代码不完整(远程根本没有这个py模块)。重新上传一下。

3.2.3 循环引用问题

出现循环引用,错误栈有个特殊的明显的标志:有某个import语句在错误栈出现了两次。

解决步骤(选择其一即可):

  • 找到错误栈出现两次的import语句,改成局部引用。
  • 重新构建代码模块。

3.2.4 当前目录优先问题

import引用时,会优先在当前模块查找,如果找到某个模块就不再根据sys.path去查找。如果当前目录下存在同名模块xxx,就可能找不到xxx模块下的模块。

解决步骤:修改当前目录下的文件名,或者改用局部引用。

3.2.5 sys.modules问题

这个出现极少。具体原因是,python解释语句时,会对import语句进行一个优化,把import后的模块会维护一个字典即 sys.modules,如果后续import某个模块,发现已经在 sys.modules 里,就不会去sys.path去查找,而是直接通过sys.modules去引用。

解决方案:尊网嘱。

  • 4
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值