从包中加载mathematica包

时间:2011-12-05 12:29:52

标签: wolfram-mathematica mathematical-packages

我或多或少有以下设置。在~/path/to/my/packages我有两个包package1.mpackage2.m。例如,每个包的大纲如下:

BeginPackage["package1`"]
Unprotect@@Names["package1`*"];
ClearAll@@Names["package1`*"];

Begin["`Private`"]

vecNorm[vec_?VectorQ]:=Module[{},Return[Sqrt[vec.vec]]];

End[]
Protect@@Names["package1`*"];
EndPackage[]

现在,我的问题是我想使用vecNorm package1.m中定义的package2.m。如何在package1内加载({安全地)package2

目前,我按如下方式手动加载两个包:

SetDirectory[StringJoin[NotebookDirectory[], "packages"]];
Needs["package1`"]
Needs["package2`"]

保存在~/path/to/my中的笔记本中。我想手动加载 {/ em> package2,而后者将自动加载package1。一般来说,我想要一个尽可能少地改变mathematica路径等的解决方案。什么应该是实现这一目标的最佳做法?

PS :安全地我的意思是,将来,当我定义package3时将使用vecNorm并将加载package1同样也不会发生冲突。

1 个答案:

答案 0 :(得分:14)

有两种通常推荐的加载包的方法。一个是所谓的公共导入,在你的设置中它将作为

完成
BeginPackage["package2`",{"package1`"}]

(* Usage messages etc *) 

Begin["`Private`"]

(* code here *)

End[]
EndPackage[]

在此处,您在列表中指明要加载的包的上下文名称,该列表是BeginPackage的第二个可选参数。这种导入方式称为public,因为加载的包将在加载主包后保留在$ContextPath上,因此可以公开使用。

第二种方法称为私有导入,并以

示意性地完成
BeginPackage["package2`"]

(* Usage messages etc *) 

Begin["`Private`"]
Needs["package1`"]

(* code here *)

End[]
EndPackage[]

在此方法中,加载的第二个包只能用于加载它的包(带Needs),因此是私有导入。

您需要哪种方式取决于具体情况。除非我必须将它们公开,否则我会尝试将所有导入设为私有。但是,对于调试,首先进行公共导入可能很方便,因为那时你可以直接在顶层玩第二个包。

至于安全性,您可以通过任意数量的包装入包装,这将是安全的。当您同时将多个包加载到同一个上下文中时,只要这些包没有具有相同短名称的公共符号,这将是安全的。否则,您将遇到所谓的阴影问题,但最好尽一切努力避免这种情况(总是可能的)。