首页 文章

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

提问于
浏览
197

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

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

如果可以在文件中放置多个函数,是否有任何限制?例如,文件中的所有函数都可以从文件外部访问,还是只能从与文件同名的函数中访问?

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

9 回答

  • 35

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

    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
    
  • 8

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

    OOP功能仅在R2008a之后才得到官方支持,因此除非你想使用旧的,未记录的OOP语法,否则你的答案是否定的,正如@gnovice所解释的那样 . .

    EDIT

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

  • 0

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

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

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

    More food for thought...

    有一些方法围绕上面概述的正常函数作用域行为,例如将function handles作为输出参数传递,如SCFrenchJonas(从R2013b开始,由localfunctions函数促成)的答案中所述 . 但是,我不建议习惯于采用这种技巧,因为组织你的功能和文件可能有更好的选择 .

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

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

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

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

    • Use private functions! 如果在同一目录中有 ABC ,则可以创建一个名为 private 的子目录,并在其中放置 DEF ,每个子目录作为单独的m文件 . 这限制了它们的范围,因此只能通过上面目录中的函数(即 ABC )调用它们,并将它们保存在同一个地方(但仍然是不同的m文件):

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

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

  • 22

    我非常喜欢SCFrench的答案 - 我想指出可以很容易地修改它以使用assignin函数将函数 directly 导入工作区 . (这样做让我想起了很多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
    
  • 3

    与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);
    
  • 72

    我使用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'.
    
  • 255

    您还可以将函数与main函数一起分组到一个主文件中,如下所示:

    function [varargout] = main( subfun, varargin )
    [varargout{1:nargout}] = feval( subfun, varargin{:} ); 
    
    % paste your subfunctions below ....
    function str=subfun1
    str='hello'
    

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

  • -1

    截至R2017b,这不是正式可行的 . relevant documentation指出:

    程序文件可以包含多个功能 . 如果文件只包含函数定义,则第一个函数是main函数,它是MATLAB与文件名关联的函数 . 主函数或脚本代码后面的函数称为本地函数 . 本地功能仅在文件中可用 .

    但是,在其他答案中建议的变通方法可以实现类似的功能 .

  • 4

    我尝试使用SCFRench并在_tatave上使用Ru Hasha .

    And finally it works: 但我做了一些修改

    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());
    

    update:

    我添加了一个答案,因为 neither 对于我来说是72和20 -749237_的八度音阶 . 我写的那个作品很完美(上周五我在后来写这篇文章时对它进行了测试) .

相关问题