13

我或多或少有以下设置。在~/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[]

现在,我的问题是我想使用in中的vecNorm定义。如何从内部(安全地)加载?package1.mpackage2.mpackage1package2

目前,我手动加载这两个包,如下所示:

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

从保存在~/path/to/my. 我只想手动加载, package2这又会自动安全地加载package1。一般来说,我想要一个尽可能少地改变数学路径等的解决方案。实现这一目标的最佳实践应该是什么?

PS:安全我的意思是在将来,当我将定义package3哪个也将使用vecNorm并且将加载package1以及不会发生冲突时。

4

1 回答 1

14

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

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

(* Usage messages etc *) 

Begin["`Private`"]

(* code here *)

End[]
EndPackage[]

在这里,您在列表中指明要加载的包的上下文名称,这是BeginPackage. 这种导入方式被称为公共的,因为加载的包将$ContextPath在你的主包加载后保留在,因此将是公开可用的。

第二种方法称为私有导入,示意性地完成为

BeginPackage["package2`"]

(* Usage messages etc *) 

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

(* code here *)

End[]
EndPackage[]

在这种方法中,您加载的第二个包将仅对加载它的包可用(使用Needs),因此是私有导入。

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

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

于 2011-12-05T12:38:24.667 回答