在 DynamicModule 中打印动态变量
为什么在下面的示例中,不是 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}
编辑(阅读您的答案/评论后):
考虑更简单的示例,没有初始化
代码(以绕过 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
或从 Print
行中省略 Dynamic
,则会执行我想要的操作。我的担忧是:
为什么第二个示例无法正确打印 b 的值?没有初始化,其中(根据帮助)包含“首次显示 DynamicModule 时要计算的表达式”。另根据帮助:“首次评估
DynamicModule
时,首先对局部变量进行初始赋值,然后评估Initialization
选项的任何设置。”帮助应为:“初始化:首次显示
DynamicModule
的结果时计算的表达式”,这意味着Print
屏幕上的语句并不构成DynamicModule
的“结果”。如果这是正确的,那么(并且只有这样)我才明白为什么Print
语句并不意味着Dynamic
对象正确显示。
Why is it that not the value of b gets printed in the following example but the symbolname? How can I force the printing of the actual dynamic value of the variable?
a = {1, 2, 3};
DynamicModule[{b},
Print[Dynamic[b]];
{Dynamic[a], Dynamic[b]}
,
Initialization :> (b = Length[a]; a = a + 2)
]
output:
b$107
Out[2]= {{3, 4, 5}, 3}
Edit (after reading your answers/comments):
Consider the more simple example, without Initialization
code (to get around WReach's example):
a = {1, 2, 3};
DynamicModule[{b = Length[a]},
Print[Dynamic[b]];
{Dynamic[a], Dynamic[b]}
]
output:
During evaluation of In[4]:= b$602
Out[5]= {{1, 2, 3}, 3}
Note, that this example does what I want to if I use Module
instead of DynamicModule
or leave out Dynamic
from the Print
line. My concerns are:
Why does this second example fail to print the value of b correctly? There is no Initialization, which (according to the help) contains "an expression to evaluate when the DynamicModule is first displayed". Also according to help: "When
DynamicModule
is first evaluated, initial assignments for local variables are made first, and then any setting for theInitialization
option is evaluated."The help should read: "Initialization: an expression to evaluate when the result of
DynamicModule
is first displayed", meaning that aPrint
statement onscreen does not constitute the "result" of theDynamicModule
. If this is correct, then (and only then) I understand why thePrint
statement does not mean that theDynamic
object appears correctly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信发生这种情况是因为调用
Print
语句时尚未显示Dynamic
对象b
,因此初始化尚未完成制成。我记得,动态
功能只有在实际、可见地显示后才会运行。请参阅 为什么这不起作用?动态选择以获取更多信息。
针对您的更新,我的理论是前端永远不会显示
Print
中的Dynamic
语句,因此它永远不会真正初始化。也就是说,它仍然是一个唯一的占位符,等待最终显示时由b
的动态值填充。从下面的示例中可以看出,分配 RHS 评估发生在正文
Print
之前,至少通过前端中的显示顺序来衡量。此外,我们看到Print
“进入”Dynamic
并获取由DynamicModule
创建的唯一符号名称,并将其打印出来。我们可以使用ToString
使Print
按原样显示整个表达式。同样,如果我们从该字符串中提取符号名称,并将其转换为实际符号,则在打印之前,我们会得到确实已经分配的预期值。输出:
I believe this happens because the
Dynamic
objectb
has not been displayed at the time thePrint
statement is called, and therefore the initialization has not been made. As I recall,Dynamic
functionality does not operate until it is actually, visibly displayed.See Why won't this work? Dynamic in a Select for more information.
In response to your update, my theory is that the
Dynamic
statement withinPrint
in never displayed by the FrontEnd, and therefore it is never actually initialized. That is, it remains a unique placeholder, waiting to be filled by the dynamic value ofb
when it is finally displayed.One may see from the example below that the assignment RHS evaluation takes place before the body
Print
, at least by measure of the display order in the FrontEnd. Further, we see thatPrint
"goes inside"Dynamic
and takes the unique symbol name created byDynamicModule
, and prints that. We can useToString
to causePrint
to display the entire expression as it is. Likewise, if we extract the symbol name from that string, and convert it to an actual symbol, before printing, we get the expected value that has indeed already been assigned.Output:
文档的更多信息部分描述了关键行为动态模块:
如果您将
Print
语句添加到Initialization
选项,则事件的确切顺序会变得更加明显,从而:产生三个单元格:
包含
b$107
的单元格code> 是DynamicModule
内Print
的结果。然后,我们得到结果单元格(此处标记为Out[7]
)。最后,我们看到Initialization
中Print
语句输出的第三个单元格。如果检查
Out[7]
单元格的单元格表达式,您会发现本地化变量是b$$
。这与第一个单元格中的变量b$107
不同。这种差异可归因于DynamicModule
文档中描述的“双重作用域”。b$107
单元格包含一个Dynamic
框,如果我们为b$107
赋值,就可以看到。更新
针对更新后的问题...
返回原始表达式(没有
初始化
中额外的Print
),确切的序列事件如下:首先,在“为局部变量提供唯一名称[...]就像模块”之后,对
DynamicModule
的主体进行评估。也就是说,计算此表达式:此表达式的结果是列表
{Dynamic[a], Dynamic[b$107]}
。作为副作用,会创建一个包含b$107
的动态单元格,但该单元格现在已从进一步考虑中删除,因为它不是评估结果的一部分。现在,“[{Dynamic[a], Dynamic[b$107]}
] 的版本被包装在DynamicModule中”并返回。对此进行评估并隐式打印以生成如下输出单元表达式:特别注意,
b$107
被重命名为$CellContext`b$$
作为的函数DynamicModule
符号本地化。现在,当框显示且可见时,将计算初始化
表达式。关键点是包含DynamicModule 单元。
b$107
的打印单元没有以任何方式耦合到最终的The crucial behaviour is described under the More Information section of the documentation for DynamicModule:
The exact sequence of events becomes more apparent if you add a
Print
statement to theInitialization
option, thus:resulting in three cells:
The cell containing
b$107
is the result of thePrint
inside theDynamicModule
. Then, we get the result cell (taggedOut[7]
here). Finally, we see the third cell output byPrint
statement in theInitialization
.If you inspect the cell expression of the
Out[7]
cell, you will find that the localized variable isb$$
. This is different from the variable in the first cell, which isb$107
. This difference is attributable to the "double scoping" described in theDynamicModule
documentation. Theb$107
cell contains aDynamic
box, as can be seen if we assign a value tob$107
.Update
In response to the updated question...
Returning to the original expression (without the extra
Print
in theInitialization
), the exact sequence of events is as follows:First, the body of the
DynamicModule
is evaluated after giving "unique names to local variables [...] just like Module". That is, this expression is evaluated:The result of this expression is the list
{Dynamic[a], Dynamic[b$107]}
. As a side-effect, a dynamic cell containingb$107
is created but that cell is now removed from further consideration as it is not part of the result of the evaluation. Now, "a version of [{Dynamic[a], Dynamic[b$107]}
] is wrapped in DynamicModule" and returned. This is evaluated and implicitly printed to produce an output cell expression like this:Note particularly that
b$107
is renamed to$CellContext`b$$
as a function ofDynamicModule
symbol localization. TheInitialization
expression is now evaluated as the box is displayed and visible.The key point is that the printed cell containing
b$107
is not coupled in any way to the finalDynamicModule
cell.