如何将目录转换为包?

Tob*_*ler 12 matlab package

我有一个目录,其中包含一些应该放入包中的辅助函数.第一步显然是命名目录,+mypackage\所以我可以调用函数mypackage.somefunction.问题是,一些函数依赖于彼此,显然MATLAB要求包函数通过显式声明包名来调用同一个包中的函数,所以我必须重写所有函数调用.更糟糕的是,如果我决定重命名包,所有函数调用也必须重写.当我cd的名字以a开头时,当我进入目录时,这些函数甚至不再正常工作+.

有没有比重写更容易的解决方案?或者至少有一些自我引用的东西import this.*可以促进未来的软件包重命名?


编辑我注意到类和静态方法也是如此,这就是我将自引用部分放入这个单独的问题的原因.

gno*_*ice 15

事实上,我不知道你应该经常重命名你的包.在我看来,MATLAB中的一个背后的整个想法是将一组相关的函数和类组织成一个集合,您可以轻松地使用或分发为"工具箱",而不必担心名称冲突.

因此,将函数和类放入包中就像是为了制作精美的工具集而执行的最后一步,因此您真的没有太多理由重命名包.此外,您只需要将包名称添加到包函数调用之前.

...(暂停思考,如果我建议的是一个好主意;))...

但是,如果你真的想避免必须通过你的包并使用新的包名前置函数调用,一种方法是使用该函数mfilename获取当前运行的包函数的完整文件路径,解析路径字符串找到父包目录(以"+"开头),然后将结果传递给import函数以导入父包.您甚至可以将这些步骤放在一个单独的函数中packagename(要求您也使用该函数evalin):

function name = packagename

  % Get full path of calling function:
  callerPath = evalin('caller', 'mfilename(''fullpath'')');

  % Parse the path string to get package directories:
  name = regexp(callerPath, '\+(\w)+', 'tokens');

  % Format the output:
  name = strcat([name{:}], [repmat({'.'}, 1, numel(name)-1) {''}]);
  name = [name{:}];

end
Run Code Online (Sandbox Code Playgroud)

然后,您可以将它放在包函数的最开头,以自动将它们包含在其父包命名空间中:

import([packagename '.*']);
Run Code Online (Sandbox Code Playgroud)

这是一个好主意吗?好吧,如果您每次调用包函数都这样做,我不确定计算的影响是什么.此外,如果您将包嵌套在包中,您将从中获得输出packagename,如下所示:

'mainpack.subpack.subsubpack'
Run Code Online (Sandbox Code Playgroud)

并且调用import将仅包括直接父包subsubpack.如果您还想包含其他父包,则必须从上面的字符串中依次删除最后一个包并导入该字符串的其余部分.

总之,这是不是一个非常干净的解决方案,但它可以使你的包很容易就能以这种方式重新命名.但是,我仍然建议最好将创建一个包作为创建核心工具集的过程中的最后一步,在这种情况下,重命名应该是一个不太可能的场景,并且使用包名称预先包含函数调用只需要做一次.

  • @Tobias:如果我遇到这种情况,我会首先解决一个包名(例如`mypack`),然后咬紧牙关,然后查看所有代码,找到包函数相互调用的位置,在mypack之前. `调用将它们正确地限定在包中.通过使用一些依赖性工具可以使这一步更容易,这些工具可以告诉您哪些函数调用或被哪些其他函数调用.[这个问题](http://stackoverflow.com/questions/5518200/automatically-generating-a-diagram-of-function-calls-in-matlab)链接到一些这样的选项. (2认同)