模块工作方式

Mathematica 中模块的基本工作方式非常简单. 任何模块每一次使用时,就产生一个新符号去代表它的每一个局部变量. 新符号的名字被唯一地给定,它不能跟任何其它名字冲突. 命名的方法是在给定的局部变量后加 ,并给出唯一的序号.

从全局变量 $ModuleNumber 的值可以找到序列号. 该变量计算 Module 的任何形式所使用的总次数.

Module 中产生形如 x$nnn 的符号去代表每个局部变量.

Mathematica 中模块的基本原理.

这里说明了模块内所产生 的符号.
任何模块每一次运行时产生的符号不同.

在绝大部分情况下,不需要直接涉及模块内产生的实际符号. 但在一个模块的执行过程中打开对话时就会看到这些符号. 同样,用函数如 Trace 等也能观察模块的计算.

Trace 观察模块内部产生的符号.
In[3]:=
Click for copyable input
Out[3]=
在模块中打开对话.
In[4]:=
Click for copyable input
在对话内看到为 等局部变量产生的符号.
In[5]:=
Click for copyable input
Out[5]=
可以像其它符号一样来处理这些符号.
In[6]:=
Click for copyable input
Out[6]=
从对话返回.
In[7]:=
Click for copyable input
Out[7]=

在某些情况下,明确返回在模块中产生的符号是很方便的.

可以明确地返回在模块中产生的符号.
In[8]:=
Click for copyable input
Out[8]=
可以把这些符号像其它符号一样处理.
In[9]:=
Click for copyable input
Out[9]=
Unique[x]产生形如 唯一名称的新符号
Unique[{x,y,...}]产生一个新符号表

通过唯一的名称产生新符号.

函数 UniqueModule 一样产生新符号. 每次调用 Unique 时,$ModuleNumber 增加,故可保证新符号的名称不重复.

产生唯一的名称以 开头的新符号.
In[10]:=
Click for copyable input
Out[10]=
每调用一次 Unique 就得到一个序列号更大的符号.
In[11]:=
Click for copyable input
Out[11]=
对一个集合调用 Unique 时,得到每个符号有相同的序列号.
In[12]:=
Click for copyable input
Out[12]=

可以用标准 Mathematica ?name 机制得到在模块中或用函数 Unique 产生符号的信息.

执行这一模块产生符号 .
In[13]:=
Click for copyable input
Out[13]=
这里可以看到所产生的符号.

模块 Module 所产生的符号与计算中的符号性能相同. 但这些符号具有 Temporary 属性,当不再使用时它们会被系统删除,所以在模块内产生的符号当模块执行完时就被删除. 那些明确返回的符号才能继续存在.

这里显示了在模块内产生的新变量 .
这个新变量在模块执行结束时被删除,所以这里不再出现.

应该意识到对所产生的符号用 等符号名完全是一种约定. 一般地,可以对任何符号用这类符号,但这样做时可能会与模式 Module 所产生的符号重合.

重要的一点是由模式 Module 所产生的符号的唯一性仅仅在 Mathematica 的一个进程中是唯一的. 决定符合序列数的变量 $ModuleNumber 在每个进程的开始时总是重新设置.

这意味着将含有所产生符号的表达式存在一个文件中,然后在另一个进程中打开该文件时无法保证不冲突.

避免这种冲突的一个途径是在每个进程的开始时直接设置不同的 $ModuleNumber,特别,当设置$ModuleNumber=10^10 $SessionID 时就可以避免任何冲突. 全局变量 $SessionID 给出刻划特定Mathematica 进程的唯一数. 这个变量的值由日期和时间、所用计算的ID、以及特定 Mathematica 过程的ID等决定.

$ModuleNumberModuleUnique 所产生符号的序列号
$SessionID在每个 Mathematica 进程中都不重复的数

决定所产生符号序列号的变量.

在产生了决定局部变量的符号后,Module[vars, body] 就用这些符号计算 body. 首先取模块中出现的 body 的实际表达式,用 With 将每个局部变量的名称用所产生的符号代替,然后模块 Module 来计算结果中表达式的值.

重要的是 Module[vars, body] 仅将所产生的符号代入 body 的实际表达式中. 但它不把这些符号代入 body 所调用的但不直接出现在 body 中的代码中.

"块和局部值" 节将讨论如何用 Block 去建立以不同方式工作的"局部值".

由于 没有直接出现在模块的body中,故没有它的局部值.
In[17]:=
Click for copyable input
Out[17]=

大部分情况下,通过 Module[vars, body] 的直接输入来在 Mathematica 中建立模块. 由于 Module 函数具有属性HoldAll,所以在模块执行之前 body 将维持不计算的状态.

Mathematica 中还可以建立动态模块. 新符号的产生以及向 body 中的代入总是在模块执行时进行,而不是在模块作为 Mathematica 输入建立时进行.

这里立即计算模块的内部,直接给出 的值.
In[18]:=
Click for copyable input
Out[18]=
New to Mathematica? Find your learning path »
Have a question? Ask support »