Wolfram 系统会话的全局特征
在任何交互进程中,Wolfram 系統循环运行. 等待输入、处理输入、显示结果,然后再返回来等待新的输入. 作为这个 “主循环” 的一部分,Wolfram 系統保持和使用各种全局对象. 用这些对象工作常常是很有用的.
In[n] | 第 n 个输入行的表达式 |
InString[n] | 第 n 个输入行的文本形式 |
%n or Out[n] | 第 n 个输出行的表达式 |
Out[{n1,n2,…}] | 输出表达式列表 |
%%…%
(
n
times) or
Out[-n] | 倒数第 n 个输出行的表达式 |
MessageList[n] | 处理第 n 行时产生的信息列表 |
$Line | 当前行号(可重新设置) |
$HistoryLength | 要保持前面输入和输出的行数 |
Wolfram 系統默认保存进程过程中所有输入和输出行. 在很长的进程中,这会占用大量的计算机内存. 但通过使用 Unprotect[In,Out],后跟 Clear[In,Out] 明显清除 In 和 Out 的值可以删除输入和输出行. 通过设置全局变量 $HistoryLength 也可以令 Wolfram 系統保存前面的有限行.
注意在一个进程的任何点,可以重新设置计数器 $Line,这样就可以用新行去覆盖前面的行.
$PreRead | 在送往 Wolfram 系統之前用于每个输入字符串的函数 |
$Pre | 在计算之前用于每个表达式的函数 |
$Post | 计算之后用于每个表达式的函数 |
$PrePrint | 在 Out[n] 赋值后,但在结果显示之前使用的函数 |
$SyntaxHandler | 用于任何一个有语法错误输入行的函数 |
对于一个特定输入行而言,标准的主循环从得到一个输入文本字符串开始. 特别是需要处理特殊字符串时,有可能在Wolfram 系統进一步加工之前需要修改这个文本字符串. 这可以通过将一个函数赋以全局变量 $PreRead 的值来实现. 该函数将作用于这个字符串,其结果将作为这个特殊输入行实际的输入字符串.
当 Wolfram 系統成功地读入一个表达式后就可计算. 在计算之前,Wolfram 系統使用指定为 $Pre 值的函数,计算之后使用指定为 $Post 值的函数. 注意,除非 $Pre 函数保持其变量不计算,则该函数与 $Post 有相同的效果.
令 Wolfram 系統对每个结果使用函数 N:
Wolfram 系統产生结果后使用某个指定的 $Post 函数,然后取出结果赋于 Out[$Line]. 下一步 Wolfram 系統显示该结果,但在这之前要使用某个指定为 $PrePrint 值的函数.
删除赋于 $PrePrint 的值:
在一般的 Wolfram 系統进程中产生各种类型的输出. 一般来说,每一种类型的输出送往确定的输出通道,如 "流和底层的输入输出" 中所述. 每一个输出通道有一个全局变量,其给出要包含在这个输出通道中的输出流列表.
$Output | 标准输出和由 Print 产生的文本 |
$Echo | 每个输入行的回响(储存在 InString[n] 中) |
$Urgent | 输入提示和其他紧急输出 |
$Messages | 标准信息和由 Message 产生的输出 |
通过修改在给定输出通道中的流列表,可以重新定向或者复制特定类型的 Wolfram 系統输出. 例如,通过打开一个到文件的输入流,且将其包含在 $Echo 列表中,就可以将每个对 Wolfram 系統的输入存在一个文件中.
Streams[] | 所有打开的流列表 |
Streams["name"] | 所有具有指定名称的打开流列表 |
$Input | 当前输入流的名称 |
$InputFileName | 当前搜索输入的文件绝对路径 |
函数 Streams 显示所有输入、输出和在一个 Wolfram 系統进程中的某一点打开的其他流. 变量 $Input 给出特定点Wolfram 系統输入流的名称. 在 Get 命令的执行过程中,重新设置 $Input. Get 也将 $InputFileName 设置为输入文件的绝对路径.
$MessagePrePrint | 用于信息中给出的表达式的函数 |
$Language | 信息所用默认语言列表 |
像 "消息" 节讨论的一样,典型的信息包含一个表达式的序列,与 StringForm 的信息文本相结合. $MessagePrePrint 给出在显示之前作用于表达式的函数. $MessagePrePrint 的默认值对于文本格式化为 Short,而对于排版来说是 Short 和 Shallow 的组合.
Wolfram 系統允许对全局变量 $Epilog 给出一个值去指定 Wolfram 系統实际退出之前进行的运算. 用这种方法可以让 Wolfram 系統在退出之前保存某些对象.
$IgnoreEOF | 是否忽略文件结束字符 |
像 "字符串中的特殊字符" 中讨论的一样,Wolfram 系統通常并不按特殊方式处理特殊字符. 但可能有一个例外,用默认设置 $IgnoreEOF=False 时,Wolfram 系統能识别文件结束字符. 当在标准交互 Wolfram 系統进程的一个输入行仅接收到一个文件结束字符时,Wolfram 系統就退出这个进程.
在标准交互式进程中,可以用 Wolfram 语言命令 Dialog 去建立一个子进程或者对话. 在进行计算的过程中,可以用对话与 Wolfram 语言相互作用. 像 "追踪运算" 中提到的一样,TraceDialog 在一个表达式计算的过程中的指定点自动调用 Dialog. 另外,在计算过程中要中断 Wolfram 语言时,一般用对话检查其状态.
Dialog[] | 启动 Wolfram 语言对话 |
Dialog[expr] | 启动对话,将 expr 作为 % 的当前值 |
Return[] | 从对话返回,取 % 的当前值作为返回值 |
Return[expr] | 从对话返回,取 expr 作为返回值 |
用 Return 从一个对话中退出:
如果在 Wolfram 语言进程的第 10 行开始一个对话,则该对话的第一行就标记为 In[11]. 对话的相继行就标记为 In[12]、In[13] 等. 当退出对话时,在主循环中的下行将标记为 In[11]. 此时,仍然可以引用对话中所产生的结果 Out[11]、Out[12] 等. 但这些结果当主循环进行到行 In[12]、In[13] 等时就会被覆盖.
在一个标准 Wolfram 语言进程中,通过观察输入和输出行是否缩进可以判断是否处于一个对话中. 当从对话中再调用对话时,将缩进两个层次. 一般地,在 d 嵌套循环中的缩进由对象 DialogIndent[d] 的输出形式决定. 通过定义该对象的格式就可以指定在所用的 Wolfram 语言进程中的对话怎样缩进.
DialogSymbols:>{x,y,…} | 其值相对于对话是局部的符号 |
DialogSymbols:>{x=x0,y=y0,…} | 具有初始值的符号 |
DialogProlog:>expr | 在开始对话之前计算的表达式 |
Dialog 选项.
不论对 DialogSymbols 进行什么设置,Dialog 总是将 $Line、$Epilog 和 $MessageList 的值作为局部处理. 注意,对 $Epilog 给出一个值时,在退出对话时其就自动计算.
退出对话时可以明确用 Return[expr] 指定返回值. 不这样做时,返回值就是对话中最后产生的一个值.
DateList[] | 按形式 {year,month,day,hour,minute,second} 给出当前的本地日期和时间 |
DateList[TimeZone->z] | 给出时区 z 中的当前日期和时间 |
$TimeZone | 给出所用计算机系统设定的时区 |
Wolfram 语言 DateList 函数的返回值是所用计算机系统设定的当前日期和时间. 其假定夏令时等已经在所用计算机系统中进行了处理. 并且假定已经对所用计算机系统设置了适当的时区.
变量 $TimeZone 返回所用计算机系统设定的当前时区. 时区按小时数给出,加上 Greenwich 标准时间(GMT)后就得到正确的当地时间. 例如,美国东部标准时间(EST)对应于时区 . 注意,夏令时校正必须包含在时区中,所以美国东部夏令时(EDT)对应于时区 .
AbsoluteTime[] | 从1900年1月1日起的总秒数 |
SessionTime[] | 当前 Wolfram 系统进程开始后的秒数 |
TimeUsed[] | 当前 Wolfram 系统进程开始中 CPU 使用秒数 |
$TimeUnit | 所用计算机系统中最小时间区间 |
Pause[n] | 至少暂停 n 秒 |
暂停10秒,然后重新计算时间函数. 注意,TimeUsed[] 不受暂停影响:
AbsoluteTime[date] | 从日期转换为绝对时间 |
DateList[time] | 从绝对时间转换为日期 |
可以使用 DateList["string"] 把日期字符串转换为日期列表,只要日期格式足够清楚.
为了对转换过程进行更多的控制,可以指定字符串中出现的日期元素的顺序和类型. 元素可以是字符串,如 "Year"、"Quarter"、"Month"、"MonthName"、"Day"、"DayName"、"Hour"、"AMPM"、"Minute" 或者 "Second".
DateString[] | 给出表示当前本地日期和时间的字符串 |
DateString[datespec,elems] | 给出日期的元素 elems 以及由 datespec 给定的时间 |
DatePattern[elems] | 匹配具有给定元素的日期的字符串模式 |
用户可以在字符串匹配函数中使用 DatePattern[elems] 作为字符串模式. 日期元素与 DateList 中使用的相同,虽然默认的日期元素分隔符被限制为 /、-、: 或者 . 字符. 其他分隔符可以在日期元素列表中明确给出.
DateListPlot[list] | 从具有日期坐标的数据列表中生成图线 |
DateListPlot[list,datespec] | 从具有以 datespec 指定的日期的数据列表中生成图线 |
DateListLogPlot[list] | 从具有日期坐标的数据列表中生成线性对数图线 |
DateListLogPlot[list,datespec] | 从具有以 datespec 指定的日期的数据列表中生成线性对数图线 |
DateListPlot 可以用来使用日期或时间的水平坐标画出数据图形. 日期可以是列表、字符串或者绝对时间,分别对应于DateList、DateString 和 AbsoluteTime. 日期指定值 datespec 可以赋给具有给定数据 {y1,y2,…} 的相关日期. DateListLogPlot 允许用户使用对数垂直标度画出数据图形.
Timing[expr] | 计算 expr,并且返回所需的CPU时间列表,包括取得的结果 |
AbsoluteTiming[expr] | 计算 expr,给出采用的绝对时间 |
Timing 用来计算与单个 Wolfram 语言表达式计算有关的时间. Timing 与 TimeUsed 的增量对应. 注意,这仅包含与在 Wolfram 语言内核中表达式实际计算有关的时间. 表达式的输出格式化时间以及与外部程序有关的时间没有包括在内.
这个时间也依赖于进行计算时 Wolfram 语言进程的确切状态. 许多 Wolfram 语言所用的内部优化依赖于前面计算的细节. 例如,Wolfram 语言经常使用前面的计算结果,以避免不必要的重复计算. 另外,第一次按某种特殊方式调用一些Wolfram 语言函数时他们建立一些内部表,再次按同一种方式调用时运行就快得多. 由于这些原因,一个运算在同一个 Wolfram 语言进程的不同点进行时所用的时间不一定相同.
给出这个运算所需要的 CPU 时间. 其中,使计算结果作为空值 Null 给出:
TimeConstrained[expr,t] | 计算表达式 expr,t 秒钟以后中断计算 |
TimeConstrained[expr,t,failexpr] | 没有满足时间限制时返回 failexpr |
在交互式地使用 Wolfram 语言时,经常要进行一个计算,但这个计算时间如果太长时,我们要退出该计算. 可以用 TimeConstrained 在一个程序中模拟这个过程. TimeConstrained 计算一个表达式,到一定的时间后,在没有完成时就中断这个计算,返回 $Aborted 或者所指定的表达式.
用 TimeConstrained 可以令 Wolfram 语言在限定的时间内按一种特定的方式处理一个问题,当这种处理方式没有成功时就转向另一种处理方式. 但要注意到当 Wolfram 语言在某一计算过程中不能中断时,TimeConstrained 可能会超时. 另外,不同计算机系统的运行速度不同,所以使用 TimeConstrained 的程序往往在不同的计算机系统中会给出不同的结果.
MemoryInUse[] | 当前 Wolfram 系统所使用内存的字节数 |
MaxMemoryUsed[] | 在这个进程中 Wolfram 系统所使用内存的最大字节数 |
Wolfram 系统使用内存时很仔细,每次当所产生的中间结果不再使用时,Wolfram 系统就立即回收分配给它的内存. 这意味着在进程的任意点,Wolfram 系统仅保存实际需要的那些表达式,不保存后面不需要的对象.
经常出现的一个问题是在某一计算机系统中 Wolfram 系统实际能使用多少内存. 通常某个时刻在该计算机上运行的所有过程能使用的内存是一个确定的量. 有时候该内存量等于该计算机中 RAM 的物理字节数. 常常还包括一些虚拟内存,这是通过与存储设备交换数据而得到的.
运行 Wolfram 系统时,数据和代码都需要空间. 完整的 Wolfram 系统代码一般有几兆字节. 对任何特定的计算而言,通常仅使用其代码的一部分. 然而在计算 Wolfram 系统数据的总有效空间时,不要忘记 Wolfram 系统代码所占用的空间. 另外还要包括正在计算机上运行的其他过程所占用的空间. 运行的作业少时,自己的作业就可以使用更多的内存.
MemoryConstrained[expr,b] | 计算 expr,当所需要的内存大于 b 时放弃 |
MemoryConstrained[expr,b,failexpr] | 当没有满足内存限制时,返回 failexpr |
MemoryConstrained 与 TimeConstrained 的工作过程相同. 当所需要的内存超过指定值时,MemoryConstrained 就试图放弃所给的计算. 与 TimeConstrained 相同,在放弃计算之前所使用的实际内存可能会超过给定值.
一个要点是 ByteCount 给出的总是存储一个表达式时所需的最大内存. Wolfram 系统通常使用少得多的内存去存放这个表达式. 主要问题是该表达式中有多少子表达式可以共用.
在 f[1+x,1+x] 等表达式中,这两个子表达式 1+x 完全相同,但实际上不一定能存放在计算机内存的同一块内存中. ByteCount 假设所有子表达式都不共用,在此基础上给出存放表达式所需要的字节数. 但要看到一旦使用了 /. 操作符等运算后,就破坏了子表达式的共用.
然而可以通过使用函数 Share 明确告诉 Wolfram 系统去共用子表达式. 用这一方法,可以大大减少存放一个表达式时所需的实际内存.
在大部分计算机系统中,运行一个程序时所需的内存分为两部分:由程序明确分配的内存和 “堆栈空间”. 在程序中每次调用一个内部例行子程序时,一定量的堆栈空间就用来存放与这个调用有关的参数. 在许多计算机系统中,由一个程序所使用的堆栈空间的最大值必须事先给出. 当指定的堆栈空间被超过时,该程序通常就退出.
在 Wolfram 系统中,堆栈空间的主要用途之一就是处理 Wolfram 系统函数的相互调用. 所有这样的调用被明确记录在Wolfram 系统 Stack 中,如 "运算堆栈" 中所述. 用户可以通过设置全局参数 $RecursionLimit 控制这个堆栈的大小. 应该将这个参数设置得足够小以保证在所用计算机系统中不会用尽堆栈空间.
因此,例如要判断程序是否应该调用诸如 NotebookWrite 的函数时,就要确定该程序是否在使用这个笔记本前端的一个 Wolfram 语言会话中运行. 通过检测全局变量 $Notebooks 就能达到以上目的.
$Notebooks | 一个笔记本前端是否正在使用 |
$BatchInput | 输入是否按批处理模式给出 |
$BatchOutput | 输出是否按批处理模式给出,没有添加标签等 |
$CommandLine | 用来启动 Wolfram 语言内核的原始命令行 |
$ParentLink | 指定启动内核程序的 WSTP LinkObject (内核直接启动时为 Null) |
$ProcessID | 操作系统分配给 Wolfram 系统内核进程的 ID |
$ParentProcessID | 调用 Wolfram 系统内核的进程 ID |
$Username | 运行 Wolfram 系统内核的用户登录名 |
Environment["var"] | 由操作系统定义的变量值 |
在一个特定的 Wolfram 语言会话中使用了诸如 x 的变量时,可能要求其与另一个 Wolfram 语言会话中的 x 相同或不同. 为了保证不同会话中的对象不同,Wolfram 语言支持 $SessionID 变量,利用开始时间、进程 ID和机器 ID 等对每一个 Wolfram 语言会话给出不同的值,不论这些会话是在同一机器或不同的机器上运行.
$SessionID | 对每一个 Wolfram 语言会话设置的不同且唯一的编号 |
Wolfram 语言提供了判断运行内核版本的各种不同的全局变量. 这一点在编写利用一些功能(如第6版中的新功能)的程序时是重要的. 可以用 $VersionNumber 去检查这些功能是否可用.
$Version | 给出所用 Wolfram 语言版本的字符串 |
$VersionNumber | Wolfram 系统的内核版本号(如 11.2) |
$ReleaseNumber | 在所用计算机系统上 Wolfram 系统内核的版本号 |
$CreationDate | 该 Wolfram 系统版本创建的日期(用 DateObject 格式) |
$System | 描述所用计算机系统的完全字符串 |
$SystemID | 指定所用计算机系统的简短字符串 |
$ProcessorType | 所给计算机系统的处理器类型 |
$MachineType | 所用计算机系统的总类型 |
$ByteOrdering | 所用计算机系统上产生字节的排序约定 |
$OperatingSystem | 所用的基本操作系统 |
$SystemCharacterEncoding | 所用操作系统编码的默认原始字符 |
Wolfram 语言使用 $SystemID 的值去标记不同计算机系统下版本文件的目录,参见 "读取和写入 Wolfram 系统文件"和 "WSTP 程序的可移植性" 中讨论的. $SystemID 相同的计算机系统一般是二进制兼容的.
$MachineAddresses | 当前 IP 地址列表 |
$MachineName | 正在运行 Wolfram 语言的计算机名 |
$MachineDomains | 计算机所在的当前网络域 |
$MachineID | Wolfram 系统赋给该计算机的唯一 ID |
$ActivationKey | Wolfram 语言运行所需的激活密钥 |
$LicenseExpirationDate | 许可证过期的日期 |
$NetworkLicense | 是否是网络许可证 |
$LicenseServer | 许可证服务器的机器全名 |
$LicenseProcesses | 在该许可证下当前运行的 Wolfram 系统处理器数目 |
$MaxLicenseProcesses | 由许可证所提供的最大进程数目 |
$PasswordFile | 启动内核时的密码文件 |
命令行选项和环境变量
-pwfile | Wolfram 系统密码文件 |
-run | 用以运行的 Wolfram 语言输入(仅包括内核) |
-initfile | Wolfram 系统初始化文件(仅包括内核) |
-noinit | 不运行初始化文件(仅包括内核) |
-wstp | 只通过 WSTP 通讯 |
Wolfram 系统前端的命令行环境 | |
Wolfram 语言内核的命令行环境 | |
$BaseDirectory 的设置 | |
初始化
- 运行许可证管理操作.
- 运行传递给内核可执行文件的任意 -run 选项中的 Wolfram 语言命令.
- 在系统范围内的初始化文件 $BaseDirectory/Kernel/init.m 中运行 Wolfram 语言命令.
- 在用户指定的初始化文件 $UserBaseDirectory/Kernel/init.m 中运行 Wolfram 语言命令.
- 在自动加载目录中载入 init.m 和 Kernel/init.m 文件.
- 开始运行主循环.
主循环
- 读取输入.
- 对已定义的输入字符串运用 $PreRead 函数.
- 如果需要的话,显示语法警告.
- 如果有语法错误的话,运用 $SyntaxHandler 函数.
- 赋以 InString[n].
- 对已定义的输入表达式运用 $Pre 函数.
- 赋以 In[n].
- 计算表达式.
- 运用已定义的 $Post 函数.
- 赋以 Out[n],解开任何格式化的包装.
- 运用已定义的 $PrePrint 函数.
- 赋以 MessageList[n] 并且清除 $MessageList.
- 如果表达式不为 Null,显示该表达式.
- 增加 $Line.
- 清除任何待处理的退出.
消息
在一个 Wolfram 系统会话中,消息或者可以通过对 Message 的明确调用,或者在执行其他内置函数的过程中产生.
f::name::lang | 在指定语言中的消息 |
f::name | 在默认语言中的消息 |
General::name | 具有给定名称的一般消息 |
如果对一个特定的消息没有指定语言,那么消息文本在每个由 $Language 指定的语言中搜索. 如果 f::name 未被定义,那么搜索 General::name 的定义. 如果仍然未找到消息,那么对 f 和 "name" 运用给 $NewMessage 定义的任意值.
当阻止消息在计算过程中显示,Quiet[expr] 计算 expr. Off[message] 阻止指定的消息显示. Check 允许用户决定是否在表达式计算过程中产生特定消息. $MessageList 和 MessageList[n] 记录所有在 Wolfram 系统会话的一个特定行的计算过程中产生的所有消息.
终止
Exit[] or Quit[] | 终止 Wolfram 系统 |
$Epilog | 在 Wolfram 系统退出前计算的符号 |
$IgnoreEOF | 当接收到一个文件末尾的字符,是否退出交互式 Wolfram 系统会话 |
end.m | 当 Wolfram 系统终止时读取的文件 |
如果从一个文件获取 Wolfram 语言的输入,那么到达文件末尾时 Wolfram 系统将退出. 如果用户正在交互式地使用 Wolfram 系统,如果收到一个文件结束字符(通常为 Ctrl+d),仍然将退出. 用户可以通过设置 $IgnoreEOF=True 终止 Wolfram 系统的运行.
网络许可证管理
网络许可证由 Wolfram 系统许可证管理程序 mathlm 控制,运行在服务器上. 无论什么时候使用具有网络许可证的 Wolfram 系统,程序必须在运行. 通常用户想要设置自己的系统,使得无论什么时候启动系统,也启动 mathlm.
当 mathlm 不是直接从命令行启动的时候,通常把自己设为背景进程,并且继续运行直到明确被终止. 注意,如果一个 mathlm 进程正在运行,那么任何其他用户试图启动的 mathlm 进程将自动立即退出.
-logfile file | 对 file 写入许可证服务器行为日志 |
-loglevel n | 如何做出详细日志条目(1至4) |
-logformat string | 使用由 string 指定的日志格式 |
-language name | 用于消息的语言(默认为 English) |
-pwfile file | 使用指定的 mathpass 文件(默认为 ./mathpass) |
-timeout n | 在 n 个小时以后暂停已经停止的 Wolfram 系统任务的授权 |
-restrict file | 使用指定的限制文件 |
-mathid | 打印许可证服务器的 MathID,然后退出 |
-foreground | 在前台运行 mathlm,登陆到 stdout |
-install | 把 mathlm 作为 Windows 服务安装(只用于 Microsoft Windows) |
-uninstall | 把 mathlm 作为 Windows 服务卸载(只用于 Microsoft Windows) |