在下面的示例中,为什么不是b的值不是打印的,而是符号名?如何强制打印变量的实际动态值?

a = {1, 2, 3};

DynamicModule[{b},
 Print[Dynamic[b]];
 {Dynamic[a], Dynamic[b]}
 ,
 Initialization :> (b = Length[a]; a = a + 2)
 ]

输出:
b$107

Out[2]= {{3, 4, 5}, 3}

编辑(阅读您的答案/评论后):

考虑一个没有Initialization代码的更简单的示例(绕过WReach的示例):
a = {1, 2, 3};

DynamicModule[{b = Length[a]},
 Print[Dynamic[b]];
 {Dynamic[a], Dynamic[b]}
 ]

输出:
During evaluation of In[4]:= b$602

Out[5]= {{1, 2, 3}, 3}

请注意,如果我使用Module而不是DynamicModule或从Dynamic行中删除了Print,则此示例将实现我想要的功能。我担心的是:
  • 为什么第二个示例无法正确打印b的值?没有初始化(根据帮助),该初始化包含“用于在DynamicModule首次显示时进行评估的表达式”。同样根据帮助:“当首先评估DynamicModule时,首先进行局部变量的初始分配,然后评估Initialization选项的任何设置。”
  • 帮助应该显示为:“初始化:一个表达式,用于在首次显示 DynamicModule结果时进行评估”,这意味着屏幕上的Print语句不构成DynamicModule的“结果”。如果这是正确的,那么(并且只有)我理解为什么Print语句并不意味着Dynamic对象正确显示。
  • 最佳答案

    DynamicModule文档的“更多信息”部分下描述了关键行为:



    如果将Print语句添加到Initialization选项,则事件的确切顺序将变得更加明显,因此:

    a = {1, 2, 3};
    
    DynamicModule[{b},
     Print[Dynamic[b]];
     {Dynamic[a], Dynamic[b]}
     ,
     Initialization :> (b = Length[a]; Print["init:", b]; a = a + 2)
     ]
    

    产生三个单元格:
            b$107
    
    Out[7]= {{3, 4, 5}, 3}
    
            init:3
    

    包含b$107的单元格是PrintDynamicModule的结果。然后,我们得到结果单元格(在此处标记为Out[7])。最后,我们在Print中看到Initialization语句输出的第三个单元格。

    如果检查Out[7]单元格的单元格表达,您会发现本地化变量为b$$。这与第一个单元格中的变量b$107不同。这种差异可归因于DynamicModule文档中描述的“双重作用域”。 b$107单元格包含一个Dynamic框,可以看到,如果我们为b$107分配了一个值。

    更新

    回应更新的问题...

    返回原始表达式(Print中没有多余的Initialization),事件的确切顺序如下:

    首先,在给“类似于模块的局部变量赋予唯一名称”之后,对DynamicModule的主体进行评估。也就是说,该表达式将被评估:
    Print[Dynamic[b$107]]; {Dynamic[a], Dynamic[b$107]}
    

    该表达式的结果是列表{Dynamic[a], Dynamic[b$107]}。副作用是,创建了一个包含b$107的动态单元格,但由于该单元格不是评估结果的一部分,因此现在不再考虑该单元格。现在,“[{Dynamic[a], Dynamic[b$107]}]的一个版本包装在DynamicModule中”并返回。对此进行评估并隐式打印以产生如下输出单元格表达式:
    Cell[BoxData[
     DynamicModuleBox[{$CellContext`b$$ = 3},
      RowBox[{"{",
       RowBox[{
        DynamicBox[ToBoxes[$CellContext`a, StandardForm],
         ImageSizeCache->{57., {2., 8.}}], ",",
        DynamicBox[ToBoxes[$CellContext`b$$, StandardForm],
         ImageSizeCache->{7., {0., 8.}}]}], "}"}],
      DynamicModuleValues:>{},
      Initialization:>($CellContext`b$$ =
        Length[$CellContext`a]; $CellContext`a = $CellContext`a + 2)]], "Output"]
    

    请特别注意,根据b$107符号本地化功能,$CellContext`b$$重命名为DynamicModule。现在将在显示并显示该框时评估Initialization表达式。

    关键在于,包含b$107的打印单元不以任何方式耦合到最终的DynamicModule单元。

    10-08 17:16