【发布时间】:2011-06-21 05:27:44
【问题描述】:
有没有办法分离打开的 Mathematica 笔记本,使它们不共享任何变量?如何让它共享一些变量而不是全部?
【问题讨论】:
有没有办法分离打开的 Mathematica 笔记本,使它们不共享任何变量?如何让它共享一些变量而不是全部?
【问题讨论】:
是的,有。我建议阅读与 Mathematica 上下文相关的文档。简而言之,所有变量都属于某个上下文(命名空间),并且所有变量都可以通过它们的“ContextName`varName”形式的完全限定名称来访问。如果您只使用“varName”,Mathematica 将在 $ContextPath 中搜索上下文(尝试评估变量 $ContextPath 以查看它是什么),并将使用找到该变量的第一个上下文。此外,每个笔记本都指定了一个上下文(存储在变量$Context 中),其中存储了所有变量(除非使用完全限定名称)。
默认情况下,所有笔记本的上下文都是“全局”。同样默认情况下,所有笔记本的 $ContextPath 包括“Global`”上下文(以及“System`”和其他一些)。最终结果是变量在笔记本之间共享,这很快就会变得烦人。但是,有一个简单的解决方案。要为笔记本创建“私有”上下文,请评估以下内容:
SetOptions[EvaluationNotebook[], CellContext -> Notebook]
将为这个笔记本分配一个唯一的上下文(评估变量 $Context 以查看它是什么)。此外,全局上下文将从 ContextPath 中删除(尝试在上面的 SetOptions[...] 之前和之后评估 $ContextPath 以查看发生了什么。)
[更新:正如 rcollyer 在新的 Mathematica 堆栈交换中指出的那样,要将此选项设置为新笔记本的默认值,请执行以下操作:打开选项检查器(Ctrl+Shift+O ),将范围(在顶部的下拉菜单中)从“选择”更改为“全局首选项”;在左侧展开节点 Cell Options -> Evaluation Options,并将 CellContext 设置更改为“Notebook”。]
现在,以下是创建共享上下文的方法:
Begin["SharedContext`"];
varShared1 = "Shared string";
End[];
或者,你可以直接输入
SharedContext`varShared1 = "Shared string";
现在您可以使用完全限定名称(“SharedContext`varShared1”可以在任何笔记本中使用),或者您可以将上下文添加到 $ContextPath:
AppendTo[$ContextPath, "SharedContext`"]
如果您在所有笔记本中执行此操作,则 varShared1 将在没有完全限定名称的情况下可见。
总而言之,上下文的工作方式与许多其他搜索路径非常相似。然而,有许多微妙之处(例如,如果一个符号已经在其他上下文中定义,那么 Begin["SharedContext`"]/End[] 块可能不会像您期望的那样工作 - 符号的现有上下文将用于代替 SharedContext`),因此我建议进行健康的实验并仔细阅读文档。
【讨论】:
setPrivate[],当我想在另一个笔记本中复制现有笔记本的上下文时,我只需输入spawnScratch[]。我已经用了一年多了,发现它很方便。代码在这里:github.com/leoalekseyev/mma-context
我不确定这是否是明智之举,但无论如何。
这是两个笔记本的示意图。它可以概括,但并不简单。
打开两个笔记本
在每个菜单中 (评估 -> 笔记本的默认值 上下文 -> 此笔记本独有) 这样,符号就不再共享了。
在每个笔记本中输入一些内容
点赞Context[] 获取笔记本
上下文
现在在每个笔记本中输入 以下代码
。
Needs["Experimental`"];
SetAttributes[f, HoldFirst];
f[s_, val_] := ToExpression@StringJoin["Notebook$$17$799580`",
ToString@Unevaluated@s, "=", ToString@val];
ValueFunction[t] = f
Notebook$$17$799580 是 THE OTHER Notebook 的上下文(这应该可以“自动”获得,但这只是概念证明。
现在当你想分享一个符号时输入
f[symbolToShare]
就是这样。
您可以双向共享该值,也可以仅在一个方向共享该值,仅在您想要的笔记本中输入 f[x] 作为 x 的源值。另一台笔记本将获得更新后的值,但不会将其更新回来。
HTH!
编辑
走向自动化:
您可以获得所有其他打开的笔记本上下文来更新您的共享符号:
ctxs[]:= Complement[Contexts["Notebook$$*"],
Flatten@Union[{Context[]},
StringCases[Contexts["Notebook$$*"], __ ~~ "Private" ~~ __]]]
所以你的 f 会变成这样(未测试)
f[s_, val_] := ToExpression@StringJoin[#,
ToString@Unevaluated@s, "=", ToString@val]&/@ctxs[];
【讨论】:
要为所有笔记本提供独特的上下文,请打开 Options Inspector 并设置
单元格选项 → 评估选项 → 单元格上下文 到Notebook。
【讨论】: