• Python from import导包ModuleNotFoundError No module named,找不到模块问题



    在学习Flask框架的蓝图时,遇到导包时用到了`from . 模块 import 对象`,然后试了试直接 import会报错,直接告诉我找不到模块,发现问题以此记录。

    场景

    有一个flask框架的项目,目录结构如下:

    有一个主包pro_flask,然后下面有两个子包admin和web,还有和pro_flask同级的启动文件

    在这里插入图片描述

    我在与admin和web同级的__init__.py文件中,导入admin和web里的一些资源。

    代码如下:

    在导入admin和web中的资源时,告诉我ModuleNotFoundError: No module named 'admin'

    from flask import Flask
    
    # 以下 import的admin和web,是admin和web包下__init__.py中定义的对象
    from admin import admin		# 项目启动后,这里会报错
    from web import web		# 项目启动后,这里会报错
    
    • 1
    • 2
    • 3
    • 4
    • 5

    admin包下的__init__.py文件

    from flask import Blueprint
    
    admin = Blueprint(				# 需要在其他模块中导入这个 admin 蓝图对象
        'admin',
        __name__,
        template_folder='templates',
        static_folder='static'
    )
    from . import views
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    web包下的__init__.py文件

    from flask import Blueprint
    
    web = Blueprint(				# 需要在其他模块中导入这个 web 蓝图对象
        'web',
        __name__,
        template_folder='templates',
        static_folder='static'
    )
    from . import views
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    了解下import和from …import区别

    参考的网上大佬的笔记

    import

    import tkinter
    
    • 1

    (1)引用包
    import引入的是包中根目录下__init__.py中的全部内容,包括其中的类、类内部的公有属性、类内部的公有方法、方法等内容.(该种方式导入包的本质就是执行__init__.py文件)

    (2)引用模块
    (该种方式导入模块的本质是将模块解释执行一遍,并赋值给tkinter: module_name = “module_name.py all code”)

    ===> import module_name —> module_name.py —> module_name.py的位置 —> sys.path(本质是一个列表)

    from…import

    (1)引用包
    (from … import …引入的是在包中根目录下__init__.py和某个文件的内容)但是,我们知道,导入包是没有意义的,最终的目的是导入包下面的模块。(该种方式导入包)

    (2)引用模块
    (该种方式当如模块的本质是讲module_name.py文件掰开,把想要的部分放入当前文件执行一遍。)

    分析

    看了网上大佬的分析以及解决方案,自己分析下

    一般情况下,python会把一些默认的包目录和用户自定义包所在的目录加载到python的搜索模块的路径集中(sys.path,是一个list列表),然后用户在进行导包时,python会去搜索的模块路径集中去寻找,所导入包的所在目录是否在这个搜索的模块路径集中,如果不存在,那么就会抛出异常找不到模块。

    代码分析:启动类中,我们打印一下python搜索的模块路径集

    from pro_flask import app
    
    import sys
    print(sys.path)
    
    if __name__ == '__main__':
        app.run()
    -------------------------------------------------------
    ['D:\environment\python-workspace\flaskProject', 'D:\environment\python\DLLs', 'D:\environment\python\lib', 'D:\environment\python', 'D:\environment\python-workspace\flaskProject\venv', ........]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注意列表中这个'D:\environment\python-workspace\flaskProject',就是上面截图中项目所在的路径。

    结论:也就是说,这个项目所在目录被加载到了python的搜索模块路径集中,所有导入包的操作都必须要从项目的目录开始找,否则就会出问题

    解决方案

    方案一(绝对路径)

    导入模块时,从项目的根目录找起

    from flask import Flask
    
    from pro_flask.admin import admin	# 从项目根目录下找起就可以
    from pro_flask.web import web
    
    • 1
    • 2
    • 3
    • 4

    方案二(相对路径, 推荐)

    导入时,使用 . 表示从当前文件所在目录找

    from flask import Flask
    
    from . admin import admin	# 从当前文件所在目录下开始找
    from . web import web
    
    • 1
    • 2
    • 3
    • 4

    同理,如果从上级目录开始找,那么可以用

    from .. xxx import xxx
    
    • 1

    参考

    参考自

    import和from … import区别文章

    sys.path文章


    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    Linux- 计划任务crontab命令的使用
    【21天学习经典算法】冒泡排序(附Python完整代码)
    6种常见分布式唯一ID生成策略及它们的优缺点对比
    远距离WiFi无线传输方案,CV5200模组通信应用,无线自组网技术
    己知一棵有 2011 个结点的树,其叶结点个数为 116,该树对应的二叉树无右孩子的结点个数是
    git强制删除本地分支 git branch -D
    UniCode 常用字符大全
    OpenCV14-图像平滑:线性滤波和非线性滤波
    大数据Kubernetes(K8S)命令指南 超级详细!
    Netty源码学习9——从Timer到ScheduledThreadPoolExecutor到HashedWheelTimer
  • 原文地址:https://blog.csdn.net/m0_67402236/article/details/126113892