本文详解如何在 Flask 项目中成功导入具有内部相对依赖的第三方修改版包(如 DeOldify),解决因 from deoldify import device 等相对路径导入失败导致的 ImportError,并提供可落地的目录结构改造、__init__.py 配置及绝对导入方案。
本文详解如何在 flask 应用中成功导入具有内部相对依赖的第三方修改版包(如 deoldify),解决因 from deoldify import device 等相对路径导入失败导致的 importerror,并提供可落地的目录结构改造、__init__.py 配置及绝对导入方案。
在 Flask 项目中直接导入像 DeOldify/image_colorizer.py 这类自带内部相对导入逻辑的模块时,常见错误并非代码写错,而是 Python 的模块解析机制与项目结构不匹配所致。核心问题在于:image_colorizer.py 中的 from deoldify import device 是包内相对导入,但当它被 app.py(作为顶层脚本运行)直接导入时,Python 无法将 DeOldify/ 视为一个有效包上下文,导致 deoldify 模块不可见。
✅ 正确解法:将 DeOldify 转为可安装的本地包 + 使用绝对导入
1. 补全包结构(关键!)
确保每个参与导入的目录都包含 __init__.py 文件(可为空),使 Python 识别为合法包:
revitalize/
├── app.py
├── __init__.py # ← 新增:使 revitalize 成为根包
├── static/
├── templates/
├── GFPGAN/
│ ├── __init__.py # ← 新增
│ ├── experiments/
│ ├── gfpgan/
│ ├── inputs/
│ ├── results/
│ └── inference_gfpgan.py
└── DeOldify/
├── __init__.py # ← 新增(必须!)
├── deoldify/
│ ├── __init__.py # ← 新增(确保 deoldify 可被导入)
│ └── ...
├── fastai/
│ ├── __init__.py # ← 新增(若 fastai 是其自定义模块)
│ └── ...
├── fid/
├── test_images/
├── result_images/
└── image_colorizer.py⚠️ 注意:__init__.py 是包识别的基石,缺失即导致 ModuleNotFoundError。
2. 修改 image_colorizer.py —— 统一使用绝对导入
将原文件中的相对风格导入(如 from deoldify import device)改为基于 DeOldify 包名的绝对导入,明确告诉 Python “deoldify 是 DeOldify 子包”:
# DeOldify/image_colorizer.py
from DeOldify.deoldify import device
from DeOldify.deoldify.device_id import DeviceId
from DeOldify.deoldify.visualize import *
def ColorIMG():
device.set(device=DeviceId.GPU0)
# ... 其余逻辑保持不变3. 在 app.py 中正确导入
此时 DeOldify 已是合法包,可直接通过包名导入:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
# app.py
from flask import Flask, request, render_template, send_from_directory, redirect
from werkzeug.utils import secure_filename
import os
# ✅ 正确:从 DeOldify 包导入模块
from DeOldify.image_colorizer import ColorIMG # 直接导入函数(推荐)
# 或
# from DeOldify import image_colorizer # 导入模块,调用时用 image_colorizer.ColorIMG()
app = Flask(__name__)
reconstruct = True
loc1 = 'inputs/whole_imgs' # 注意:Windows 也建议用 '/' 或 os.path.join
loc2 = 'DeOldify/test_images'
upload = loc1 if reconstruct else loc2
app.config['UPLOAD'] = upload
@app.route('/', methods=['GET', 'POST'])
def file_upload():
if request.method == 'POST':
f = request.files['file']
filename = secure_filename(f.filename)
f.save(os.path.join(app.config['UPLOAD'], filename))
return redirect('/reconstruct')
return render_template('index.html')
@app.route('/colorize', methods=['GET', 'POST'])
def colorize():
ColorIMG() # 直接调用函数
return render_template("index.html")
if __name__ == '__main__':
app.run(debug=True, port=4339)4. (可选但推荐)通过 pip install -e 开发安装
在项目根目录(revitalize/)下创建 setup.py,让 Python 将整个项目视为可安装包:
# revitalize/setup.py
from setuptools import setup, find_packages
setup(
name="revitalize",
version="0.1",
packages=find_packages(),
)然后执行:
cd revitalize pip install -e .
这会将 revitalize 注册为可导入包,彻底规避路径问题,且支持 IDE 自动补全。
? 关键总结
- ❌ from .deoldify import ... 在 app.py 中无效——顶层脚本不支持相对导入;
- ✅ 必须补全所有 __init__.py,否则包结构不成立;
- ✅ image_colorizer.py 内部改用 from DeOldify.deoldify import ... 等绝对路径;
- ✅ app.py 中用 from DeOldify.image_colorizer import ColorIMG 显式导入;
- ? 若仍报错,检查 Python 运行时工作目录是否为 revitalize/(推荐在该目录下执行 python app.py);
- ? 对复杂依赖包(如 DeOldify),优先考虑 pip install 官方版本或 fork 后发布到私有源,避免手动维护嵌套结构。
通过以上改造,DeOldify 及其内部依赖即可被 app.py 稳定调用,不再触发 ImportError: No module named 'deoldify'。

















