使用Context作为Mathematica中的作用域构造

时间:2011-04-14 19:51:55

标签: wolfram-mathematica scoping

考虑到我的previous question在大型Mathematica项目中关于数值和分析“模式”之间切换的解决方案,我想到了使用Context作为范围构造的想法。

基本思想是在自己的上下文中进行所有数值赋值,例如

Begin["Global`Numerical`"]
par1 = 1;
par2 = 2;
...
End[]

并在全局背景下拥有所有复杂的分析函数,矩阵等。

理想情况下,我可以在全局环境中工作,并使用简单的Begin[Global'Numeric']切换到数字的所有内容,然后切换回End[]

不幸的是,这样做不起作用,例如全局上下文中定义的f[par1_,par2_,...] := foo将不会使用已在Global的子上下文中定义的par1par2等。

有没有办法让子上下文从父上下文继承定义?是否有其他方法可以使用上下文来创建一个简单的可切换范围?

1 个答案:

答案 0 :(得分:5)

嗯,通过适当调整$ContextPath,这是一种解决问题的方法(我认为)是你的问题:

SetOptions[EvaluationNotebook[], CellContext -> "GlobalTestCtxt`"];
Remove[f, GlobalTestCtxt`Numerical`f, par1, par2];
f[par1_, par2_] := {par1, par2};

savedContextPath = $ContextPath;
Begin["GlobalTestCtxt`Numerical`"];
Print[{$ContextPath, $Context}];
$ContextPath = DeleteCases[$ContextPath, "GlobalTestCtxt`"];
par1 = 1;
par2 = 2;
End[];
$ContextPath = savedContextPath;

现在,这将进行分析评估:

f[par1, par2]

这就是数字:

savedContextPath = $ContextPath;
Begin["GlobalTestCtxt`Numerical`"];
$ContextPath = Prepend[$ContextPath, $Context];
f[par1, par2]
End[];
$ContextPath = savedContextPath;

我说它很脆弱的原因是,除非你小心,否则很容易让符号进入错误的环境。例如,假设您在评估“数字”块之前忘记在全局上下文中评估f。好吧,现在你的数字块不会简单,因为它会变成一个(完全有效的)符号GlobalTestCtxt`Numerical`f,当你第一次评估数字块时,你无意中输入了符号表。由于这样的潜在错误,我个人不使用这种方法。

编辑修复了一个错误(在数字上下文中进行作业时,有必要隐藏“全局”上下文)