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		# 项目启动后,这里会报错

admin包下的__init__.py文件

from flask import Blueprint

admin = Blueprint(				# 需要在其他模块中导入这个 admin 蓝图对象
    'admin',
    __name__,
    template_folder='templates',
    static_folder='static'
)
from . import views

web包下的__init__.py文件

from flask import Blueprint

web = Blueprint(				# 需要在其他模块中导入这个 web 蓝图对象
    'web',
    static_folder='static'
)
from . import views

了解下import和from …import区别

参考的网上大佬的笔记

import

import tkinter

(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', ........]

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

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

解决方案

方案一(绝对路径)

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

from flask import Flask

from pro_flask.admin import admin	# 从项目根目录下找起就可以
from pro_flask.web import web

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

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

from flask import Flask

from . admin import admin	# 从当前文件所在目录下开始找
from . web import web

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

from .. xxx import xxx

参考

参考自

import和from … import区别文章

sys.path文章


原文地址:https://blog.csdn.net/weixin_45248492

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Jinja2:是Python的Web项目中被广泛应用的模板引擎,是由Python实现的模板语言,Jinja2 的作者也是 Flask 的作者。他的设计思想来源于Django的模板引擎,并扩展了其语法和一系列强大的功能,其是Flask内置的模板语言。
Fullcalendar日历使用,包括视图选择、事件插入、编辑事件、事件状态更改、事件添加和删除、事件拖动调整,自定义头部,加入el-popover显示图片、图片预览、添加附件链接等,支持手机显示。
监听QQ消息并不需要我们写代码,因为市面上已经有很多开源QQ机器人框架,在这里我们使用go-cqhttp官方文档:go-cqhttp如果您感兴趣的话,可以阅读一下官方文档,如果不想看,直接看我的文章即可。
【Flask框架】—— 视图和URL总结
python+web+flask轻量级框架的实战小项目。登录功能,后续功能可自行丰富。
有了这个就可以配置可信IP,关键是不需要企业认证,个人信息就可以做。
本专栏是对Flask官方文档中个人博客搭建进行的归纳总结,与官方文档结合事半功倍。 本人经验,学习一门语言或框架时,请首先阅读官方文档。学习完毕后,再看其他相关文章(如本系列文章),才是正确的学习道路。
本专栏是对Flask官方文档中个人博客搭建进行的归纳总结,与官方文档结合事半功倍。基础薄弱的同学请戳Flask官方文档教程 本人经验,学习一门语言或框架时,请首先阅读官方文档。学习完毕后,再看其他相关文章(如本系列文章),才是正确的学习道路。 如果python都完全不熟悉,一定不要着急学习框架,请首先学习python官方文档,一步一个脚印。要不然从入门到放弃是大概率事件。 Python 官方文档教程
快到年末了 相信大家都在忙着处理年末数据 刚好有一个是对超市的商品库存进行分析的学员案例 真的非常简单~
一个简易的问答系统就这样完成了,当然,这个项目还可以进一步完善,比如 将数据存入Elasticsearch,通过它先进行初步的检索,然后再通过这个系统,当然我们也可以用其他的架构实现。如果你对这系统还有其他的疑问,也可以再下面进行留言!!!
#模版继承和页面之间的调用@app.route("/bl")def bl(): return render_template("file_2.html")主ht
#form表达提交@app.route("/data",methods=['GET','POST']) #methods 让当前路由支持GET 和
#form表达提交@app.route("/data",methods=['GET','POST']) #methods 让当前路由支持GET 和
#session 使用app.secret_key = "dsada12212132dsad1232113"app.config['PERMANENT_SESSION_LI
#文件上传@app.route("/file",methods=['GET','POST'])def file(): if request.meth
#跳转操作:redirect@app.route("/red")def red(): return redirect("/login")
#session 使用app.secret_key = "dsada12212132dsad1232113"app.config['PERMANENT_SESSION_LI
@app.route("/req",methods=['GET','POST'])def req(): print(request.headers)
#模版继承和页面之间的调用@app.route("/bl")def bl(): return render_template("file_2.html")主ht
#文件操作:send_file,支持图片 视频 mp3 文本等@app.route("/img")def img(): return send_file("1.jpg&q