从包中加载mathematica包

Dro*_*ror 13 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[]
Run Code Online (Sandbox Code Playgroud)

现在,我的问题是我想使用vecNormin package1.min中定义的package2.m.如何package1从内部加载(安全)package2

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

SetDirectory[StringJoin[NotebookDirectory[], "packages"]];
Needs["package1`"]
Needs["package2`"]
Run Code Online (Sandbox Code Playgroud)

从保存的笔记本中~/path/to/my.我想手动加载只有 package2这反过来将会自动,安全地加载package1.一般来说,我想要一个尽可能少地改变mathematica路径等的解决方案.实现这一目标的最佳做法是什么?

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

Leo*_*rin 14

有两种通常建议的加载包的方法.一个是所谓的公共导入,在你的设置中它将完成

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

(* Usage messages etc *) 

Begin["`Private`"]

(* code here *)

End[]
EndPackage[]
Run Code Online (Sandbox Code Playgroud)

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

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

BeginPackage["package2`"]

(* Usage messages etc *) 

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

(* code here *)

End[]
EndPackage[]
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • @Dror第二种方法应该可以正常工作.如果没有,这应该意味着你将第二个包放在Mathematica找不到的地方.然后,您应该将软件包重新定位到M可以找到它们的位置(例如`$ UserBaseDirectory`),或者将包含软件包的目录添加到`$ Path`变量中.实际上,要么两种导入方法都有效,要么两者都失败,所以我对你的情况感到有些困惑. (2认同)