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

发布于 2024-09-16 04:16:48 字数 227 浏览 9 评论 0原文

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

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

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

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

When I was studying for my undergraduate degree in EE, MATLAB required each function to be defined in its own file, even if it was a one-liner.

I'm studying for a graduate degree now, and I have to write a project in MATLAB. Is this still a requirement for newer versions of MATLAB?

If it is possible to put more than one function in a file, are there any restrictions to this? For instance, can all the functions in the file be accessed from outside the file, or only the function that has the same name as the file?

Note: I am using MATLAB release R2007b.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

若有似无的小暗淡 2024-09-23 04:16:48

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

m 文件中的所有后续函数,称为 本地函数 (或旧术语中的“子函数”)只能由该 m 文件中的主函数和其他本地函数调用。其他m文件中的函数不能调用它们。从 R2016b 开始,您可以向脚本添加本地函数 同样,尽管作用域行为仍然相同(即它们只能从脚本内调用)。

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

更多深思熟虑...

有一些方法可以解决上面概述的正常函数作用域行为,例如传递 函数句柄 作为输出参数,如 SCFrenchJonas(从 R2013b 开始,由 localfunctions 函数)。但是,我不建议养成使用此类技巧的习惯,因为可能有更好的选择来组织您的功能和文件。

例如,假设 m 文件 Am 中有一个主函数 A,以及局部函数 DE< /code> 和 F。现在假设您在 m 文件 BmCm 中分别有另外两个相关函数 BC,您还希望能够调用 DEF。以下是您可以选择的一些选项:

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

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

  • DEF 复制到 BmCm 作为本地功能。这将它们的使用范围限制为 ABC,但却使代码的更新和维护成为一场噩梦,因为您相同代码在不同位置的三份副本。

  • 使用私有函数 如果同一目录中有 ABC,则可以创建一个名为 private 的子目录并将 DEF 放入其中,每个都作为一个单独的 m 文件。这限制了它们的范围,因此它们只能由紧邻上面目录中的函数调用(即 ABC)并保留它们一起在同一个地方(但仍然是不同的 m 文件):

    我的目录/
        是
        乙米
        厘米
        私人的/
            DM
            埃姆
            调频
    

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

The first function in an m-file (i.e. the main function), is invoked when that m-file is called. It is not required that the main function have the same name as the m-file, but for clarity it should. When the function and file name differ, the file name must be used to call the main function.

All subsequent functions in the m-file, called local functions (or "subfunctions" in the older terminology), can only be called by the main function and other local functions in that m-file. Functions in other m-files can not call them. Starting in R2016b, you can add local functions to scripts as well, although the scoping behavior is still the same (i.e. they can only be called from within the script).

In addition, you can also declare functions within other functions. These are called nested functions, and these can only be called from within the function they are nested. They can also have access to variables in functions in which they are nested, which makes them quite useful albeit slightly tricky to work with.

More food for thought...

There are some ways around the normal function scoping behavior outlined above, such as passing function handles as output arguments as mentioned in the answers from SCFrench and Jonas (which, starting in R2013b, is facilitated by the localfunctions function). However, I wouldn't suggest making it a habit of resorting to such tricks, as there are likely much better options for organizing your functions and files.

For example, let's say you have a main function A in an m-file A.m, along with local functions D, E, and F. Now let's say you have two other related functions B and C in m-files B.m and C.m, respectively, that you also want to be able to call D, E, and F. Here are some options you have:

  • Put D, E, and F each in their own separate m-files, allowing any other function to call them. The downside is that the scope of these functions is large and isn't restricted to just A, B, and C, but the upside is that this is quite simple.

  • Create a defineMyFunctions m-file (like in Jonas' example) with D, E, and F as local functions and a main function that simply returns function handles to them. This allows you to keep D, E, and F in the same file, but it doesn't do anything regarding the scope of these functions since any function that can call defineMyFunctions can invoke them. You also then have to worry about passing the function handles around as arguments to make sure you have them where you need them.

  • Copy D, E and F into B.m and C.m as local functions. This limits the scope of their usage to just A, B, and C, but makes updating and maintenance of your code a nightmare because you have three copies of the same code in different places.

  • Use private functions! If you have A, B, and C in the same directory, you can create a subdirectory called private and place D, E, and F in there, each as a separate m-file. This limits their scope so they can only be called by functions in the directory immediately above (i.e. A, B, and C) and keeps them together in the same place (but still different m-files):

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

All this goes somewhat outside the scope of your question, and is probably more detail than you need, but I thought it might be good to touch upon the more general concern of organizing all of your m-files. ;)

脸赞 2024-09-23 04:16:48

一般来说,您的问题的答案是否定的,每个文件不能定义多个外部可见函数。不过,您可以将函数句柄返回给本地函数,一种方便的方法是将它们设为结构体的字段。这是一个示例:

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

Generally, the answer to your question is no, you cannot define more than one externally visible function per file. You can return function handles to local functions, though, and a convenient way to do so is to make them fields of a struct. Here is an example:

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

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

function z=fun2
  z=1;
end

And here is how it could be used:

>> myfuns = makefuns;
>> myfuns.fun1(5)    
ans =
     5
>> myfuns.fun2()     
ans =
     1
最笨的告白 2024-09-23 04:16:48

在单个文件中拥有多个可单独访问的函数的唯一方法是定义 使用面向对象编程的静态方法。您可以通过 myClass.static1()myClass.static2() 等方式访问该函数。

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

编辑

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

The only way to have multiple, separately accessible functions in a single file is to define STATIC METHODS using object-oriented programming. You'd access the function as myClass.static1(), myClass.static2() etc.

OOP functionality is only officially supported since R2008a, so unless you want to use the old, undocumented OOP syntax, the answer for you is no, as explained by @gnovice.

EDIT

One more way to define multiple functions inside a file that are accessible from the outside is to create a function that returns multiple function handles. In other words, you'd call your defining function as [fun1,fun2,fun3]=defineMyFunctions, after which you could use out1=fun1(inputs) etc.

土豪我们做朋友吧 2024-09-23 04:16:48

我真的很喜欢 SCFrench 的答案 - 我想指出的是,可以轻松修改它以使用 allocatein 函数将函数直接导入到工作区。 (这样做让我想起了很多Python的“从y导入x”的做事方式)

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

I really like SCFrench's answer - I would like to point out that it can easily be modified to import the functions directly to the workspace using the assignin function. (Doing it like this reminds me a lot of Python's "import x from y" way of doing things)

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

And then used thusly:

>> makefuns
ans =
Done importing functions to workspace

>> fun1(123)
ans =
   123

>> fun2()
ans =
     1
筱武穆 2024-09-23 04:16:48

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

Along the same lines as SCFrench's answer, but with a more C# style spin..

I would (and often do) make a class containing multiple static methods. For example:

classdef Statistics

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

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

end

As the methods are static you don't need to instansiate the class. You call the functions as follows:

data = 1:10;

mean = Statistics.MyMean(data);
std = Statistics.MyStd(data);     
提赋 2024-09-23 04:16:48

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

I define multiple functions in one .m file with Octave and then use the command from within the .m file where I need to make use of the functions from that file:

source("mycode.m");

Not sure if this is available with 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'.
蘑菇王子 2024-09-23 04:16:48

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

function [varargout] = main( subfun, varargin )
[varargout{1:nargout}] = feval( subfun, varargin{:} ); 

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

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

You could also group functions in one main file together with the main function looking like this:

function [varargout] = main( subfun, varargin )
[varargout{1:nargout}] = feval( subfun, varargin{:} ); 

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

Then calling subfun1 would look like this:
str=main('subfun1')

给妤﹃绝世温柔 2024-09-23 04:16:48

截至 R2017b,这正式不可能。 相关文档指出:

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

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

As of R2017b, this is not officially possible. The relevant documentation states that:

Program files can contain multiple functions. If the file contains only function definitions, the first function is the main function, and is the function that MATLAB associates with the file name. Functions that follow the main function or script code are called local functions. Local functions are only available within the file.

However, workarounds suggested in other answers can achieve something similar.

鲸落 2024-09-23 04:16:48

我尝试使用 SCFRenchRu 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 对我来说都不起作用
我写的那个工作得很好(上周五我在后来写这篇文章时测试了它)。

I have try with the SCFRench and with the Ru Hasha on octave.

And finally it works: but I have done some modification

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

Can be called in other 'm' file:

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

update:

I added an answer because neither the +72 nor the +20 worked in octave for me.
The one I wrote works perfectly (and I tested it last Friday when I later wrote the post).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文