是否可以在 MATLAB 中为每个文件定义多个函数,并从该文件外部访问它们?

Posted

技术标签:

【中文标题】是否可以在 MATLAB 中为每个文件定义多个函数,并从该文件外部访问它们?【英文标题】:Is it possible to define more than one function per file in MATLAB, and access them from outside that file? 【发布时间】:2011-04-03 22:51:06 【问题描述】:

当我攻读 EE 本科学位时,MATLAB 要求在自己的文件中定义每个函数,即使它是单行的。

我现在正在攻读研究生学位,我必须在 MATLAB 中编写一个项目。这仍然是新版本 MATLAB 的要求吗?

如果可以在一个文件中放置多个函数,对此有什么限制吗?例如,文件中的所有函数都可以从文件外部访问,还是只访问与文件同名的函数?

注意:我使用的是 MATLAB 版本 R2007b。

【问题讨论】:

【参考方案1】:

m 文件中的第一个函数(即main function)在调用该 m 文件时被调用。 要求主函数与 m 文件具有相同的名称,但为了清楚起见,它应该。当函数和文件名不同时,必须使用文件名来调用main函数。

m 文件中的所有后续函数,称为local functions(或旧术语中的“子函数”),只能由该 m 文件中的主函数和其他本地函数调用。其他 m 文件中的函数不能调用它们。从 R2016b 开始,您也可以add local functions to scripts,尽管范围行为仍然相同(即它们只能从脚本中调用)。

此外,您还可以在其他函数声明函数。它们被称为nested functions,它们只能从它们嵌套的函数中调用。它们还可以访问嵌套它们的函数中的变量,这使得它们非常有用,尽管使用起来有些棘手。

更多值得深思...

有一些方法可以绕过上面概述的正常函数范围行为,例如将function handles 作为输出参数传递,如SCFrench 和Jonas 的答案中所述(从R2013b 开始,@ 987654328@函数)。但是,我不建议养成使用这种技巧的习惯,因为可能有更好的选择来组织您的函数和文件。

例如,假设您在 m 文件 A.m 中有一个主函数 A,以及局部函数 DEF。现在假设您在 m 文件 B.mC.m 中分别有另外两个相关函数 BC,您还希望能够调用 DE 和 @987654342 @。以下是您的一些选择:

DEF 分别放在各自独立的 m 文件中,允许任何其他函数调用它们。缺点是这些函数的范围很大,不仅限于ABC,但优点是这很简单。

使用DEF 创建一个defineMyFunctions m 文件(如在Jonas 的示例中)作为本地函数和一个简单地向它们返回函数句柄的主函数。这允许您将DEF 保留在同一个文件中,但它不会对这些函数的范围做任何事情,因为任何可以调用defineMyFunctions 的函数都可以调用它们。然后,您还必须担心将函数句柄作为参数传递,以确保将它们放在需要的地方。

DEF 复制到B.mC.m 作为本地函数。这将它们的使用范围限制为仅ABC,但由于您在不同位置拥有相同代码的三个副本,因此更新和维护代码将成为一场噩梦。

使用private functions!如果你有ABC在同一个目录下,你可以创建一个名为private的子目录并放置DEF 在那里,每个都是单独的 m 文件。这限制了它们的范围,因此它们只能被上面目录中的函数调用(即ABC)并将它们放在同一个地方(但仍然是不同的 m 文件):

myDirectory/
    A.m
    B.m
    C.m
    private/
        D.m
        E.m
        F.m

所有这些都超出了您的问题范围,并且可能比您需要的更详细,但我认为触及组织所有 m 文件的更普遍问题可能会很好。 ;)

【讨论】:

最喜欢的答案选项看起来像这样^, @idigas @embert 我认为他的意思是喜欢一个问题,可以独立于喜欢的问题进行投票。【参考方案2】:

通常,您的问题的答案是否定的,您不能为每个文件定义多个外部可见函数。但是,您可以将函数句柄返回给本地函数,并且一种方便的方法是使它们成为结构的字段。这是一个例子:

function funs = makefuns
  funs.fun1=@fun1;
  funs.fun2=@fun2;
end

function y=fun1(x)
  y=x;
end

function z=fun2
  z=1;
end

下面是它的使用方法:

>> myfuns = makefuns;
>> myfuns.fun1(5)    
ans =
     5
>> myfuns.fun2()     
ans =
     1

【讨论】:

【参考方案3】:

在单个文件中拥有多个可单独访问的函数的唯一方法是使用object-oriented programming 定义STATIC METHODS。您可以以myClass.static1()myClass.static2() 等身份访问该函数。

自 R2008a 起才正式支持 OOP 功能,因此除非您想使用旧的、未记录的 OOP 语法,否则您的答案是否定的,正如 @gnovice 所解释的那样。

编辑

在文件中定义多个可从外部访问的函数的另一种方法是创建一个返回多个function handles 的函数。换句话说,您可以将定义函数称为[fun1,fun2,fun3]=defineMyFunctions,之后您可以使用out1=fun1(inputs) 等。

【讨论】:

我不会为此使用 oop,它会增加大量开销,尤其是对于静态方法。 (***.com/questions/1693429/…) @Daniel:仅当您执行大量函数调用并且方法中的计算是准即时的时,开销才明显。这两种情况通常都指向糟糕的设计——没有矢量化和无意义的功能。因此,我不会太担心。【参考方案4】:

我真的很喜欢 SCFrench 的回答 - 我想指出,它可以很容易地修改为使用 assignin 函数将函数直接导入工作区。 (这样做让我想起了很多Python的“import x from y”的做事方式)

function message = makefuns
  assignin('base','fun1',@fun1);
  assignin('base','fun2',@fun2);
  message='Done importing functions to workspace';
end

function y=fun1(x)
  y=x;
end

function z=fun2
  z=1;
end

然后这样使用:

>> makefuns
ans =
Done importing functions to workspace

>> fun1(123)
ans =
   123

>> fun2()
ans =
     1

【讨论】:

assignin('caller',...) 会更正确。您可能希望在另一个函数中使用这些函数。【参考方案5】:

与 SCFrench 的答案相同,但具有更多 C# 风格的旋转..

我会(并且经常这样做)创建一个包含多个静态方法的类。例如:

classdef Statistics

    methods(Static)
        function val = MyMean(data)
            val = mean(data);
        end

        function val = MyStd(data)
            val = std(data);
        end
    end

end

由于方法是静态的,因此您不需要实例化该类。你调用函数如下:

data = 1:10;

mean = Statistics.MyMean(data);
std = Statistics.MyStd(data);     

【讨论】:

【参考方案6】:

我使用 Octave 在一个 .m 文件中定义了多个函数,然后在需要使用该文件中的函数的 .m 文件中使用命令:

source("mycode.m");

不确定这是否适用于 Matlab。

octave:8> help source
'source' is a built-in function

 -- Built-in Function:  source (FILE)
     Parse and execute the contents of FILE.  This is equivalent to
     executing commands from a script file, but without requiring the
     file to be named `FILE.m'.

【讨论】:

不,Matlab 中没有source 命令:(【参考方案7】:

您还可以将函数组合在一个主文件中,主函数如下所示:

function [varargout] = main( subfun, varargin )
[varargout1:nargout] = feval( subfun, varargin: ); 

% paste your subfunctions below ....
function str=subfun1
str='hello'

然后调用 subfun1 将如下所示: str=main('subfun1')

【讨论】:

【参考方案8】:

从 R2017b 开始,这在官方上是不可能的。 relevant documentation 声明:

程序文件可以包含多个函数。如果文件仅包含函数定义,则第一个函数是主函数,并且是 MATLAB 与文件名关联的函数。跟在主函数或脚本代码后面的函数称为局部函数。本地函数仅在文件中可用。

但是,其他答案中建议的解决方法可以实现类似的效果。

【讨论】:

这不正是 Gnovice 在回答开头所说的吗? @Adiel 也许吧,但距离那个答案已经过去了几年,有人可能想知道是否有任何改变。 我仍然没有得到任何改变...? :) 不。除了为解决这个特定主题而添加的一些文档之外。 我写这个答案的原因是因为几个版本之前他们引入了functions you can add to the end of scripts - 所以有人可能想知道这方面是否也有任何变化(答案:没有)。【参考方案9】:

我尝试过使用 SCFRench 和 Ru Hasha 八度音阶。

终于成功了: 但是我做了一些修改

function message = makefuns
    assignin('base','fun1', @fun1);   % Ru Hasha
    assignin('base', 'fun2', @fun2);  % Ru Hasha
    message.fun1=@fun1;               % SCFrench
    message.fun2=@fun2;               % SCFrench
end

function y=fun1(x)
    y=x;
end

function z=fun2
    z=1;
end

可以在其他'm'文件中调用:

printf("%d\n", makefuns.fun1(123));
printf("%d\n", makefuns.fun2());

更新:

我添加了一个答案,因为 +72 和 +20 对我来说都不起作用。 我写的那一篇效果很好(上周五我在写这篇文章时测试了它)。

【讨论】:

如果您能解释这与您复制的两个现有答案有何不同,我将删除我的反对意见。很抱歉没有早点发表评论。我只是看不出这有什么不同,除非您将这两种方法组合到一个函数中,因此正在做一些多余的事情。另外,请插入正确的链接到您引用的答案,“+72”和“+20”非常神秘,我花了一段时间才意识到您指的是投票计数,这会随着时间的推移而改变并做出您的参考难以理解。

以上是关于是否可以在 MATLAB 中为每个文件定义多个函数,并从该文件外部访问它们?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MATLAB 中为图像使用自定义神经网络函数 [关闭]

从Matlab中的单个文件加载多个函数[重复]

如何在 Matlab Coder 中为具有不同输入数量的函数定义输入类型?

matlab怎么建立自定义函数

新星计划MATLAB-定义函数

如何在 Shopware 6 中为订单添加自定义字段?