Wolfram mathematica 从包中加载Mathematics包

Wolfram mathematica 从包中加载Mathematics包,wolfram-mathematica,mathematical-packages,Wolfram Mathematica,Mathematical Packages,我大致有以下设置。在~/path/to/my/packages中,我有两个包package1.m和package2.m。例如,每个包的大纲如下所示: BeginPackage["package1`"] Unprotect@@Names["package1`*"]; ClearAll@@Names["package1`*"]; Begin["`Private`"] vecNorm[vec_?VectorQ]:=Module[{},Return[Sqrt[vec.vec]]]; End[] P

我大致有以下设置。在
~/path/to/my/packages
中,我有两个包
package1.m
package2.m
。例如,每个包的大纲如下所示:

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

Begin["`Private`"]

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

End[]
Protect@@Names["package1`*"];
EndPackage[]
现在,我的问题是我想使用
package1.m
中定义的
vecNorm
。如何从
package2
中(安全地)加载
package1

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

SetDirectory[StringJoin[NotebookDirectory[], "packages"]];
Needs["package1`"]
Needs["package2`"]
从保存在
~/path/中的笔记本到/my
。我只想手动加载
package2
,然后将自动安全地加载
package1
。一般来说,我想要一个尽可能少地改变mathematica的路径等的解决方案。实现这一目标的最佳实践应该是什么


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

加载包有两种通常推荐的方法。一种是所谓的公共导入,在您的设置中,它将按如下方式完成

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

(* Usage messages etc *) 

Begin["`Private`"]

(* code here *)

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

第二种方法称为private import,其原理如下

BeginPackage["package2`"]

(* Usage messages etc *) 

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

(* code here *)

End[]
EndPackage[]
在这种方法中,加载的第二个包将只对加载它的包可用(使用
需要
),因此是私有导入

你需要哪种方式取决于情况。我尽量把我所有的进口商品都保密,除非我必须公开。但是,对于调试来说,首先进行公共导入可能很方便,因为这样您就可以直接在顶层使用第二个包


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

您的第一个方法解决了我的问题!谢谢至于第二个,在尝试时,似乎搜索路径有问题,
package1
无法找到
package2
-我自己也尝试过这个选项,但没有成功。@Dror第二种方法应该可以。如果没有,这意味着您将第二个包放在Mathematica找不到的地方。然后,您应该将包重新定位到M可以找到它们的位置(例如,
$UserBaseDirectory
),或者将包含包的目录添加到
$Path
变量中。事实上,要么两种导入方法都有效,要么两种方法都会失败,所以我对您的情况有点困惑。我想要一种尽可能不改变路径的解决方案,因为所有这些都在一个共享目录中,我不知道我的合作者的设置是什么。实际上,第二种方法似乎找不到基本包。我当然感到困惑;但很高兴有一个解决方案:)@Dror这两种方法在路径依赖性方面是等价的。它们都在加载带有上下文名称的包(这是一种推荐的做法),只要您将包放在M可以找到它们的地方,它们就会工作。正如我所说的,我发现您描述的情况相当令人费解-如果第二种方法失败,第一种方法也应该失败。@Dror如果您真的想深入研究,我建议您提出一个单独的问题,给出两个包的确切代码,以及您必须加载它们的确切设置(它们在哪个目录中,您使用哪个命令加载它们,错误消息是什么,等等)。然后,我或这里的其他人将能够更好地提供帮助。