You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jupyter Notebook导入父目录自定义包报错需保留run.py原有逻辑的问题

问题根因
  • 定时任务执行run.py时,工作目录为PRJ_V2根目录,Python默认将当前工作目录加入模块搜索路径sys.path,因此可以正常识别MyPackage包。
  • Jupyter Notebook启动时默认工作目录为PRJ_V2/Analysis,sys.path中未包含PRJ_V2根路径,直接导入MyPackage会触发模块不存在错误;同时Notebook本身被识别为顶层运行脚本,不支持..形式的跨父级相对导入,会触发"attempted relative import beyond top-level package"错误。
实现方案(完全保留原有run.py运行逻辑,无任何侵入修改)

所有修改仅在predictive.ipynb内完成,不改动项目原有业务代码、不调整定时任务执行流程。

第一步:将项目根目录加入Python模块搜索路径

在Notebook最开头单元格运行以下代码,自动定位PRJ_V2根目录并加入搜索路径,无需写死绝对路径:

import sys
from pathlib import Path

# 当前Notebook位于Analysis目录下,父目录即为PRJ_V2项目根
prj_root = Path.cwd().parent
if str(prj_root) not in sys.path:
    sys.path.insert(0, str(prj_root))

若你启动Notebook时的工作目录不是Analysis,只需调整prj_root的取值,保证其指向存放MyPackage文件夹的PRJ_V2根目录即可。

第二步:模块导入与热重载

常规导入

路径添加完成后,直接使用和run.py完全一致的导入语句即可,不会触发报错:

from MyPackage.myclass import Myclass

热重载实现(适配Python 3.7)

如果需要频繁修改myclass.py代码,可通过以下方式实现热重载,无需重启Notebook内核:

import importlib

target_module = "MyPackage.myclass"
# 清除已加载的模块缓存
if target_module in sys.modules:
    del sys.modules[target_module]
# 重新加载最新版本的模块
myclass_mod = importlib.import_module(target_module)
# 取出最新的类定义
Myclass = myclass_mod.Myclass

如果Myclass依赖MyPackage下的其他模块(如myclass2.py),只需把对应模块的全路径也加入缓存清理逻辑,一并删除sys.modules里的对应条目即可。

如果嫌手动执行重载代码麻烦,可以直接开启IPython自带的自动重载能力,开发效率更高,在Notebook开头加两行魔法命令即可:

%load_ext autoreload
%autoreload 2

开启后每次执行单元格代码时,IPython会自动检测所有导入的本地模块变更,自动加载最新版本代码,无需手动写重载逻辑。

方案验证
  • 原有定时任务流程完全不受影响:我们未修改PRJ_V2根目录、MyPackage目录下的任何原有代码,切换目录、激活虚拟环境、执行.\venv\Scripts\python.exe run.py的逻辑可以完全保留,运行结果和之前一致。
  • Notebook端:导入模块不再报错,热重载/自动重载功能正常,修改myclass.py代码后无需重启内核即可生效。

内容的提问来源于stack exchange,提问作者Xavi Polo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 18:51:20