Mathematica执行Needs时报上下文未创建但功能正常的问题
Mathematica自定义包加载报错问题解决
环境与包结构
- 环境:Mathematica 14.0.0(MacOS Sonoma 14.4.1)
- 包路径:
/Users/twan/LP - 目录结构:
LP/ Kernel/ init.wl Main.wl Sub.wl
各文件代码
init.wl
(* ::Package:: *) Get["LP`Main`"]
Main.wl
(* ::Package:: *) BeginPackage["LP`Main`"] dummy::usage = "dummy[s] with s a string to be formatted by the format function in LP`Sub" Begin["`Private`"] Needs["LP`Sub`"] dummy[s_] := subformat[s] End[] EndPackage[]
Sub.wl
(* ::Package:: *) BeginPackage["LP`Sub`"] subformat::usage = "subformat[s] format string s, say, to uppercase" Begin["`Private`"] subformat[s_]:= ToUpperCase[s] End[] EndPackage[]
问题现象
执行FindFile["LP"]返回预期路径/Users/twan/LP/Kernel/init.wl,但执行Needs["LP"]时弹出错误提示:Context LP was not created when Needs was evaluated。实际包功能正常,$ContextPath包含LPMain,dummy["test"]可返回TEST。
问题与解答
1. 报错原因
Needs["LP"]执行时会加载LP对应的init.wl,但你的init.wl仅加载了LPMain,并未创建LP这个顶级上下文(Context)。Needs函数的设计逻辑是:加载包后必须存在对应的顶级上下文,由于这里LP上下文从未被定义,因此触发Needs::nocont错误。
2. 消除报错的方法(除关闭警告外)
有两种规范的解决方式:
方法一:在
init.wl中显式创建LP上下文
修改init.wl,先创建LP上下文并将其加入$ContextPath,再加载子包:(* ::Package:: *) BeginPackage["LP`"] EndPackage[] Get["LP`Main`"] AppendTo[$ContextPath, "LP`"]这样
LP上下文被正式创建,Needs["LP"]`能匹配到对应的上下文,不会再报错。方法二:调整主包的上下文为
LP
将Main.wl的上下文改为顶级的LP,而非LPMain,修改后的Main.wl`如下:(* ::Package:: *) BeginPackage["LP`"] dummy::usage = "dummy[s] with s a string to be formatted by the format function in LP`Sub" Begin["`Private`"] Needs["LP`Sub`"] dummy[s_] := subformat[s] End[] EndPackage[]此时
init.wl保持Get["LP"]即可,加载后LP上下文直接存在,Needs["LP"]不会触发错误。
内容的提问来源于stack exchange,提问作者nanitous
相关产品推荐
相关产品推荐

