mathematica 包 package 的使用

refs: tutorial/SettingUpWolframLanguagePackages

使用 Get 读取 .m 文件, 能够计算文件中的表达式, 上下文中会建立起文件中的变量.
而读取 .nb 文件, 不会建立变量, 只会建立一个笔记本的符号表达式.

环境变量和工作目录

  • mma 的环境变量一共有两部分, 分别叫做 $ContextPath and $Context.
    分别是当前 上下文列表, 以及当前上下文. 参见: ref/$ContextPath, ref/$Context:

  • $ContextPath 类似 Linux 的 $PATH 环境变量. $Context 类似于 Linux 的当前工作目录.
    搜索函数以及变量名称的时候, 先搜索$ContextPath中的, 再搜索$Context中的. 这也和建立包的顺序一致.
    你可以把它看成是在文件搜索路径上附加了 .(当前工作目录).

如果遇到符号名冲突, 就使用全名调用, 或者更改 Globla` 上下文中符号的名称.

  • $ContextPath中的路径按照出现顺序搜索, 也就是说, 前面的会覆盖后面的.

  • 在 Wolfram Language 会话的任何时刻, 总是有一个当前上下文 $Context.
    你可以通过给出它们的 短名称 来引用这个上下文中的符号,
    除非该符号被 $ContextPath 上具有相同 短名称 的符号所遮蔽(shadow).
    即如果先在 $ContextPath 找到具有给定名称的符号, 它将被使用, 而不是当前 context 中的同名符号.

建立包

BeginPackage[]Begin[], 要配合相应的EndPackage[] and End[] 使用, 它们的效果不同:

  • BeginPackage["abc`"] 默认会同时设置 $Context$ContextPath,
    让会话中只剩下 abc` and System` 两个上下文.
    当然, 它也有 BeginPackage["context`",{"need1`","need2`",... 这种语法, 可以引入其他上下文.

  • Begin["abc`"] 不会更改 $ContextPath, 它只更改 $Context"abc`".

  • 此外, 调用 EndPackage[] 结束包时(不需要参数), 会将这个包, 比如 "abc`" 添加到 $ContextPath 的首元素,
    这样当你读入一个包之后, 它里面的符号就会被优先使用. 而 End[] 不会更改 $ContextPath.


所以 mma 中建立包的大概流程为:

BeginPackage["Package`"]    设置 Package` 为当前上下文, 并且把 System` 放进 $ContextPath
f::usage="text", ...    介绍打算要导出的对象(不包括其他对象), 函数名在这里建立后, 它的上下文会是Package`, 可以被外部使用
Begin["`Private`"]    设置当前上下文为  Package`Private`
f[args]=value, ...     给出包中定义的主要内容
End[]   恢复到之前的上下文(此处为 Package`)
EndPackage[]    结束包, 把Package`放到上下文搜索路径中
  • $Packages 环境变量:提供与当前 Wolfram 系统会话中已加载的所有软件包相对应的上下文列表.
  • Needs ["context`"]:如果指定的上下文尚未在 $Packages 中, 则加载适当的文件. 它会自动调用Get[]

包的文件

ref: tutorial/ModularityAndTheNamingOfThings#3434

当您创建或使用 Wolfram Language 包时, 您经常希望以独立于系统的方式来引用文件.
你可以使用上下文来做到这一点.

基本的思路是: 在每个计算机系统上都约定好了规则, 如果把本地文件系统, 与 Wolfram Language 上下文 相对应.
当你使用上下文引用文件时, Wolfram Language 自动将上下文名称转换为特定计算机系统的文件路径.

<

例如导入 Wolfram System 的标准包

<< Quaternions`

通常情况下, < 寻找的次序

  • name.mx ; DumpSave 格式的文件
  • name.mx/$SystemID/name.mx ; 特定计算机系统的 DumpSave 格式
  • name.m ; Wolfram Language 源代码格式
  • name/init.m; 特定目录的初始化文件
  • dir/...; $Path 中指定的其他目录的文件

Wolfram Language 的设置是, < 会自动尝试加载适当版本的文件.
它将首先尝试加载为您的特定计算机系统优化的 name.mx 文件.
如果没有找到, 那么它将尝试加载 name.m 文件, 它包含普通的 Wolfram Language 语法, 这种格式独立于各种计算机系统.

如果name是个目录, 那么 Wolfram Language 将尝试加载该目录下的初始化文件 init.m.
init.m 文件的目的提供一种方便的方法, 如果是package 中包含多个独立的文件
这样, 你只需给出 < 命令, 然后加载init.m 来初始化整个软件包, 读取任何需要的其他文件.

初始化文件的位置

Wolfram 系统初始化文件init.m包含启动代码, 每当 Wolfram Language 内核或前端启动时都要运行.

init.m 文件的可能位置包括如下.

  • $BaseDirectory/Kernel :内核初始化代码, 适用于所有用户
  • $UserBaseDirectory/Kernel: 内核初始化代码, 用于当前登录的用户
  • $BaseDirectory/FrontEnd: 所有用户的前端初始化代码
  • $UserBaseDirectory/FrontEnd: 前端初始化代码, 适用于当前登录的用户

Wolfram 系统 BaseDirectory 的典型子目录.

  • Applications; Wolfram Language应用程序包
  • Autoload; 启动时自动加载的软件包
  • FrontEnd; 前端初始化文件
  • Kernel; 内核初始化文件
  • Licensing; 许可证管理文件
  • SystemFiles; 一般系统文件

通过对内核$Path变量的默认设置, 只需使用<命令, 就可以从Wolfram System会话中加载附加组件.
加载 init.m 文件时, 可以再调用其他必要的文件或软件包.

通过将附加组件放在 $BaseDirectory$UserBaseDirectoryAutoload 子目录下, 你可以让 Wolfram System 在你启动内核或前端时自动加载附加组件.

  • Kernel/init.m; 初始化文件, 由内核加载.
  • FrontEnd/init.m; 由前端加载的初始化文件.
  • Documentation/; 前端要找到的帮助文档

自动导入 Package

其他教程已经讨论了使用 <Needs[package] 显式加载 Wolfram Language 软件包的方法.

然而, 有时你可能想设置 Wolfram Language, 以便在需要特定的包时自动加载它.
你可以使用 DeclarePackage 来给出在某个特定包中定义的 符号.
然后, 当这些符号之一被实际使用时, Wolfram Language 将自动加载定义该符号的.

DeclarePackage["context`", {"name1", "name2", ...}]
如果使用了 `name_i` 中的任意一个, 它隶属的包会被自动被载入.

当你 set up 了大量的 Wolfram 语言包时, 创建一个额外的 "名称文件" 通常是个好主意,
它包含了一连串的 DeclarePackage 命令, 指定了在使用特定名称时要加载的packages.
在一个特定的 Wolfram System 会话中, 你只需要显式加载 "名称文件".
然后, 所有其他的包将在需要的时候将会自动加载.

DeclarePackage 的工作方式是: 立即用你指定的名称创建符号, 但给这些符号都添加一个特殊属性 Stub.
每当 Wolfram Language 找到一个带有 Stub 属性的符号时, 它就会自动加载与该符号的上下文对应的package, 以试图找到该符号的定义.

搜索路径,$Path

$Path 给出了, 搜索外部文件所使用的搜索目录的默认列表.

  • 在不同的计算机系统中, 目录文件名 的结构可能有所不同.
  • $Path 既用于 Get 调用文件的场景, 也用于 Install 调用外部程序.
  • 如果特定函数具有Path选项, 可以覆盖$Path 的设置.
  • 目录名 是由字符串指定的. 被测试的完整文件名是FileNameJoin[{directory,name}] 的形式.
  • 在大多数计算机系统中, 以下特殊字符可用于给出 目录名.
    • . ; 当前目录
    • ... ; 层次结构中的上一级目录
    • ~ ; 用户的主目录
  • $Path 可以包含嵌套的子列表.

基本例子

  • 添加一个目录, 用于查找其中的文件, 但优先级在所有 系统默认值 之后:

    AppendTo[$Path, FileNameJoin[{$HomeDirectory, "MyPackages"}]];
    
  • 添加一个目录, 用于查找其中的文件, 但优先级在任何 系统默认值 之前:

    PrependTo[$Path, FileNameJoin[{$HomeDirectory, "MyPackages", "LookHereFirst"}]];
    

读取文件,Get

<

Details and Options

  • 如果 name 是 Wolfram Language 上下文的名称, 即用` 上下文标记字符结尾, 那么 Get 将处理该名称以查找要读取的文件.

  • 对于 "context`" 形式的名称, Get 将默认搜索以下文件.

    • context.mx; DumpSave 格式的文件
    • context.mx/$SystemID/context.mx; 本地计算机系统的 DumpSave 格式文件
    • context.wl; Wolfram 语言源代码格式的文件
    • context/Kernel/init.wl; 特定目录的内核初始化文件
    • context/init.wl; 特定目录的一般初始化文件
    • context.m; 采用 Wolfram 语言源代码格式的文件
    • context/Kernel/init.m; 某特定目录的内核初始化文件
    • context/init.m; 某特定目录的一般初始化文件
  • 对于 "context`subcontext`" 形式的名称, Get 默认会在名为 "context" 的目录下搜索 "subcontext`".

  • 如果name是一个文件名称, 任何扩展名都必须明确包括在内.

  • <<"name " 等同于 <. 可以省略双引号, 如果name 只包含

      字母, 数字,  `  /   .  \  !   -  _  :  $  *  ~  ?
    

    在 "Operator Input Forms" 中有更详细的描述.

  • 可以给出以下选项:
    CharacterEncoding; $CharacterEncoding; raw 字符使用什么编码
    Method; Automatic; 读取数据流时使用的方法
    Path; $Path; 用于搜索给定文件的目录

  • Wolfram Language 输入文件的语法错误以标准形式报告:

      filename: line: syntax error in expr
    

    即使检测到语法错误, Ge t也会继续尝试读取文件.
    然而, 如果检测到错误, $Context$ContextPath 将被重置为调用 Get 时的值.

  • Get可以读取 .nb 笔记本文件, 返回代表这些文件的 底层 box 结构.

  • Get[CloudObject[...]] 可以用来从云端获取文件.

  • Get[LocalObject[...] 可以用来从本地持久性存储中获取文件.

  • Get[Databin[...]] 可以获得 Wolfram Data Drop 中的一个 Databin 的内容.

  • 当对本地文件进行操作时, 全局变量 $Input$InputFileName 在执行 Get 时被分别设置为文件名和被读文件的完整路径.

  • 有了 Method 选项, stream就会用给定的输入流方法打开. 它覆盖 Get 解析文件名的默认方式.
    方法选项的值可以是 $InputStreamMethods 的任何成员.

选项

Path

默认情况下, 在搜索文件时会查询 $Path上的所有目录:

Get["ExampleData/language"]
Out[1]= 22 a b + 56 c + 13 a d

强制只搜索当前目录:

Get["ExampleData/language", Path -> "."]
Out[2]= $Failed

属性和关系

  • FindFile["context`"] 给出了 Get["context`"] 将加载的文件:

    FindFile["EquationTrekker`"]
    Out[1]= "/Applications/Mathematica.app/Contents/AddOns/Packages/".
    EquationTrekker/Kernel/init.m"
    

    加载该文件

    Get[%]
    

    验证 EquationTrekker 包是否真的被加载:

    Names["EquationTrekker`*"]
    Out[3]= {"DifferentialEquationTrek", "EquationTrekker", ...
    
  • 确保初始化文件只被读取一次:

    Once[Get["init.m"]]
    

你可能感兴趣的:(mathematica 包 package 的使用)