【问题标题】:Mathematica - Separating Notebooks [closed]Mathematica - 分离笔记本[关闭]
【发布时间】:2011-06-21 05:27:44
【问题描述】:

有没有办法分离打开的 Mathematica 笔记本,使它们不共享任何变量?如何让它共享一些变量而不是全部?

【问题讨论】:

    标签: wolfram-mathematica


    【解决方案1】:

    是的,有。我建议阅读与 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`),因此我建议进行健康的实验并仔细阅读文档。

    【讨论】:

    • 是的。比我的好多了。正在删除。
    • 您也可以通过“评估”>“笔记本”的默认上下文菜单(而不是 SetOptions)进行设置。[文档使用“每个单元组唯一”设置,因此不存在任何变量冲突。 ]
    • 后续问题:有没有办法让 Mathematica 将新笔记本的上下文默认设置为私有,而不必手动为每个新笔记本创建私有上下文?
    • @Joe:我不知道,但我写了一些方便的函数来轻松设置和访问私有上下文。当我开始一个新的笔记本时,我只需输入setPrivate[],当我想在另一个笔记本中复制现有笔记本的上下文时,我只需输入spawnScratch[]。我已经用了一年多了,发现它很方便。代码在这里:github.com/leoalekseyev/mma-context
    • @LeoAlekseyev:终于有人找到了让 Mathematica 将新笔记本的上下文默认设置为私有的方法:查看this answer
    【解决方案2】:

    我不确定这是否是明智之举,但无论如何。

    这是两个笔记本的示意图。它可以概括,但并不简单。

    1. 打开两个笔记本

    2. 在每个菜单中 (评估 -> 笔记本的默认值 上下文 -> 此笔记本独有) 这样,符号就不再共享了。

    3. 在每个笔记本中输入一些内容 点赞Context[] 获取笔记本 上下文

    4. 现在在每个笔记本中输入 以下代码

       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[];
    

    【讨论】:

      【解决方案3】:

      要为所有笔记本提供独特的上下文,请打开 Options Inspector 并设置 单元格选项评估选项单元格上下文Notebook

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-18
        • 1970-01-01
        • 2011-12-23
        • 1970-01-01
        • 2022-01-23
        • 2023-04-05
        • 2021-11-02
        • 2011-09-28
        相关资源
        最近更新 更多