此为 Mathematica 4 文档,内容基于更早版本的 Wolfram 语言
查看最新文档(版本11.2)

2.6.10 建立 Mathematica 程序包

在一个典型的 Mathematica 程序包中,一般引入两种类型的新符号, 一种是输出为外部程序包使用的符号,另一种仅在本程序包中使用的符号. 可以将这两种类型的符号放入不同的上下文以便区分. 通常的约定是将用作 输出的符号放在名为 Package` 的上下文内,这与程序包的名称相对应. 当这个程序包读入时,它将这个上下文加到上下文搜索路径中去, 所以在这个上下文中的符号可以通过短名调用.
仅在程序包内使用的符号习惯上放在名为 Package`Private` 的上下文内. 这个上下文没有加入到上下文的搜索路径中去. 于是这些符号只有通过 全名才能调用.

Mathematica程序包中使用上下文的约定

有一个标准的 Mathematica 指令序列用来设置程序包中的 上下文. 这些指令设置 $Context$ContextPath 的值以便新引入 的符号放在适当的上下文之中.

在程序包中的上下文控制指令标准序列

BeginPackage["Collatz`"]

Collatz::usage =
"Collatz[n] gives a list of the iterates in the 3n+1 problem,
starting from n. The conjecture is that this sequence always
terminates."

Begin["`Private`"]

Collatz[1] := {1}

Collatz[n_Integer] := Prepend[Collatz[3 n + 1], n] /; OddQ[n] && n > 0

Collatz[n_Integer] := Prepend[Collatz[n/2], n] /; EvenQ[n] && n > 0

End[ ]

EndPackage[ ]

定义在一个程序包开头使用信息的约定是在合适的上下文中产生 用作输出的符号的一个基本的技巧. 在定义这些信息时,所涉及的符号都是 用作输出的符号,这些符号都在作为当前上下文的 Package` 中产生. 在一个程序包中函数的实际定义中,有许多引入参数、局部变量等新符号. 约定将这些符号放在 Package`Private 上下文中,当程序包读入后它 不放在上下文的搜索路径之中.

这里读入前面的样本程序包

在这个包中的 EndPackage 指令将与该包对应的上下文放入上下文搜索路径中

Collatz 函数在 Collatz` 上下文中产生

参数 n 放在专用上下文 Collatz`Private`

Collatz 包中所定义的函数仅依赖于 Mathematica 的内部函数,但通常在一个 包中定义的函数依赖着另一个包中定义的函数.
为此必须有两个条件,第一是读入另一个程序包以便所需的函数有定义, 第二是上下文搜索路径必须包括这些函数所在的上下文.
可以明确告诉 Mathematica 在任一处读入程序包,使用的指令为 <<context` . 然后设置为需要时就读入某一程序包.指令 Needs["context`"] 告诉 Mathematica 当与程序包相关的 上下文不在 $Packages 列表中时就读入这个程序包.

指定独立包函数

当使用一个具有一个变量的 BeginPackage["Package`"] 时, Mathematica 仅将 Package` 上下文和内部符号上下文放在上下文的搜索路径之中. 在自定义包中涉及到其它包中的函数时,一定要确认这些包含在上下文 的搜索路径之中,这可以在 BeginPackage 的第二个变量中给出另外的上下文列表即可. BeginPackage 就自动调用 Needs,必要时读入与这些上下文对应的程序包, 确定这些上下文在上下文的搜索路径之中.

context操作函数

Begin 等上下文操作函数的执行改变了 Mathematica 翻译所输入名字的方式. 但要意识到这种改变仅对输入的下一个表达式有效,其原因是 Mathematica 总是先读入一个完整的表达式,在执行表达式的任何项之前翻译 它中的名字,于是,当一个特定表达式中执行 Begin 时,表达式中的名称已被 翻译,使 Begin 无法再产生效果.
上下文操作函数对第2个读入的完整表达式不产生影响这一事实意味着 当编写 Mathematica 程序包时必须作为分离 的表达式给出这些函数,经常是在不同的行.

x 的名字在表达式执行之前已经翻译,所以 Begin 没有作用

上下文操作函数首先用作程序包的一部分被 Mathematica 读入. 有时交互 式地应用他们也很方便. 例如,在执行一个包中定义的函数时用 TraceDialog 进行 一个对话,函数中的参数和临时变量一般是在与这个有关的上下文中. 由于 这个上下文不在上下文的搜索路径之中,Mathematica 将显示这些符号的全名, 并且需要用户输入全名去调用这些变量.但还可以用 Begin["Package`Private`"] 使包专用上下文成为当前上下文. 这就使 Mathematica 显示符号的短名, 也就可以用短名调用这些符号.