Python中import导入模块常见问题与解决方案
app/__init__.py
...
from flask_redis import FlaskRedis
from flask_login import LoginManager
import os
...
login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.oauth'
def create_app(config=“app.config”):
app = Flask(name)
with app.app_context():
app.config.from_object(config)
…
redis_store = FlaskRedis()
redis_store.init_app(app)
login_manager.init_app(app)
…
app/models.py
from . import login_manager
但是这样 import 会报错 ImportError: cannot import name 'login_manager'
参考了 Flask Web 开发一书
Python中import导入模块常见问题与解决方案
我不能重现,你需要把你启动程序的方式说一下
Python中import导入模块常见问题与解决方案
Python的import机制看似简单,但实际开发中常会遇到各种“坑”。下面我总结几个最常见的问题和对应的解决方案。
1. ModuleNotFoundError: No module named 'xxx’ 这是最经典的错误。原因就两个:要么模块确实没装,要么Python解释器找不到它。
- 解决方案:
- 没安装:用pip装一下。比如
pip install requests。 - 找不到路径:你的模块文件不在Python的搜索路径(
sys.path)里。有几种方法解决:- 临时添加路径:在代码开头用
sys.path.append('/your/module/path')。简单粗暴,但只对当前运行时有效。 - 相对导入(在包内部):如果你的文件在一个包里(有
__init__.py的文件夹),可以用点号。比如在mypackage/submodule.py里导入同包的另一个模块:from . import sibling_module。 - 设置PYTHONPATH环境变量:一劳永逸的方法,把模块所在目录加到这个环境变量里。
- 临时添加路径:在代码开头用
- 没安装:用pip装一下。比如
2. 循环导入(Circular Import) A模块导入了B,B模块又导入了A,直接卡死。
- 解决方案:
- 重构代码:这是根本办法。把两个模块共同依赖的部分抽离到第三个模块(比如
common.py)。 - 局部导入:把import语句移到函数内部,需要的时候再导入。比如:
# 文件A.py def func(): from B import something # 在函数内导入,避免在文件顶部立即执行 return something.do() - 使用importlib(动态导入):在运行时按需导入,但代码会有点绕,慎用。
- 重构代码:这是根本办法。把两个模块共同依赖的部分抽离到第三个模块(比如
3. 导入自定义模块或包 自己写的模块,尤其是多层目录的包,导入时容易迷糊。
- 解决方案:
- 确保你的目录是一个包(包含
__init__.py文件,可以是空的)。 - 理解绝对导入和相对导入。
- 绝对导入:从项目根目录或已安装的包开始写全路径。Python 3推荐这个。例如,在项目
myproject下的mypackage/subpackage/module.py中,导入另一个模块:from myproject.mypackage import another_module。这要求你的项目根目录在Python路径里。 - 相对导入:在包内部使用点号。比如在同一个
subpackage里:from . import sibling;从上一级导入:from .. import parent_module。注意:相对导入只能在包内部使用,且脚本文件(作为主程序直接运行的__main__文件)里用起来有限制。
- 绝对导入:从项目根目录或已安装的包开始写全路径。Python 3推荐这个。例如,在项目
- 确保你的目录是一个包(包含
4. 导入同名模块或属性冲突
比如你有个文件叫 email.py,又想导入标准库的 email 模块,Python会优先找到你的文件。
- 解决方案:
- 别用标准库或知名第三方库的名字命名你的文件!这是最佳实践。取名前查一下。
- 如果实在要用,可以用
importlib指定完整路径导入标准库模块,但最好还是改名。
5. __init__.py 的作用
很多人以为它只是个标记文件。
- 核心作用:
- 标识包:让Python把这个目录当成一个包。
- 初始化包:当包被导入时,
__init__.py里的代码会执行。可以在这里放包级别的初始化代码。 - 定义
__all__列表:控制from package import *时导入哪些模块。例如__all__ = ["module1", "module2"]。 - 简化导入:可以在
__init__.py里导入包下的关键子模块或函数,这样用户可以直接from package import something,而不用写很长的路径。
总结一下关键点:
- 搞清楚
sys.path,它是所有导入问题的起点。 - 项目结构清晰,合理使用包(
__init__.py)。 - 避免循环导入,必要时重构代码。
- 绝对导入更清晰,相对导入在包内更方便。
- 别让你的模块名和标准库/第三方库撞车。
一句话建议:理清模块路径和项目结构是解决大多数导入问题的关键。
这种情况不用 from 直接 import login_manager 就可以了,但 from 用包相对路径我这的确也不行,不知道怎么搞。
Python 相关的问题得写 py2 还是 py3 啊大兄弟
直接 import 也不行的
有循环导入的问题。。
把所有 import 自己代码的地方比如 blueprint 放在 creat_app()里面
能放后面就放后面
仔细分析一下包的导入过程你就知道为啥了。。
哦哦,我琢磨琢磨
解决循环引用就好了, 尽量整理好导入的模块关系
有问题可以加我们的群问,这样效率更高,这个群是一群工程师组建的面向初学者的
Python Linux 学习群, qq 群号: 278529278 ,
Php Linux 学习群, qq 群号: 476648701 ,
非商业性质,拒绝广告,只接收真正想学这方面技术的朋友,交流学习,申请请说明来自 v2ex
我感觉题主是想问 from…import…的相对导入问题。当要在 python 中使用相对导入模块,对目录结构是有要求的。
一、执行相对导入的模块(.py )文件不能作为顶层模块执行该文件夹中的 py 文件的。
二、相对导入的文件夹必须要被 python 解释器理解为包的(也就是必须要包含__init__.py )文件。
同时满足上述两个条件,才可以进行 from import 的相对导入模块的。

