【问题标题】:Load a mathematica package from within a package从包中加载mathematica 包
【发布时间】:2011-12-05 12:29:52
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: wolfram-mathematica mathematical-packages


    【解决方案1】:

    通常推荐两种加载包的方法。一种是所谓的公共导入,在你的设置中它会被完成

    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),因此是私有导入。

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

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

    【讨论】:

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