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导入模块常见问题与解决方案

10 回复

我不能重现,你需要把你启动程序的方式说一下


Python中import导入模块常见问题与解决方案

Python的import机制看似简单,但实际开发中常会遇到各种“坑”。下面我总结几个最常见的问题和对应的解决方案。

1. ModuleNotFoundError: No module named 'xxx’ 这是最经典的错误。原因就两个:要么模块确实没装,要么Python解释器找不到它。

  • 解决方案
    • 没安装:用pip装一下。比如 pip install requests
    • 找不到路径:你的模块文件不在Python的搜索路径(sys.path)里。有几种方法解决:
      1. 临时添加路径:在代码开头用 sys.path.append('/your/module/path')。简单粗暴,但只对当前运行时有效。
      2. 相对导入(在包内部):如果你的文件在一个包里(有__init__.py的文件夹),可以用点号。比如在 mypackage/submodule.py 里导入同包的另一个模块:from . import sibling_module
      3. 设置PYTHONPATH环境变量:一劳永逸的方法,把模块所在目录加到这个环境变量里。

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__ 文件)里用起来有限制。

4. 导入同名模块或属性冲突 比如你有个文件叫 email.py,又想导入标准库的 email 模块,Python会优先找到你的文件。

  • 解决方案
    • 别用标准库或知名第三方库的名字命名你的文件!这是最佳实践。取名前查一下。
    • 如果实在要用,可以用 importlib 指定完整路径导入标准库模块,但最好还是改名。

5. __init__.py 的作用 很多人以为它只是个标记文件。

  • 核心作用
    1. 标识包:让Python把这个目录当成一个包。
    2. 初始化包:当包被导入时,__init__.py 里的代码会执行。可以在这里放包级别的初始化代码。
    3. 定义 __all__ 列表:控制 from package import * 时导入哪些模块。例如 __all__ = ["module1", "module2"]
    4. 简化导入:可以在 __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 的相对导入模块的。

回到顶部