如何通过名称判断一个函数是内置的还是自定义的?

How to tell if a function is built-in or self-defined by its name?

我生成了一个复杂的MATLAB系统的调用图,我想知道哪些函数是内置的并标记它们。

只需在命令中键入 open 后跟函数名称 window

open function_name

并且 function_name 将显示在编辑器中,如果它是内置函数,您可能会在其中看到 Mathwork 版权,否则它不是

版权是这样的

%   Copyright 1993-2016 The MathWorks, Inc. 

一个函数是否是built-in最容易通过which命令看出。对于给定的函数名称,它显示定义该函数的文件的完整路径。例如,在我的机器上我看到

>> which eig
built-in (/Applications/MATLAB_R2018b.app/toolbox/matlab/matfun/eig)
>> which solve
/Users/robert/Documents/MATLAB/cvx/lib/@cvxprob/solve.m  % cvxprob method
>> which nosuchfunctionhere
'nosuchfunctionhere' not found.

告诉我 eig 是一个 built-in 函数,solve 是包 cvx 的一部分的函数,并且 nosuchfunctionhere 没有定义。

MATLAB 区分 "built-in functions"(即不存在 M-file 或 MEX-file,代码内置到 MATLAB 可执行文件中)和属于 MATLAB 包的其他函数但写成 M-files 或 MEX-files.

作为which函数会告诉你一个函数是不是"built-in",它会给你一个路径。

例如,eig 是一个 built-in 函数(给出的路径是一个包含文档的文件):

>> p = which('eig')
p =
    'built-in (/Applications/MATLAB_R2017a.app/toolbox/matlab/matfun/@single/eig)'

imshow 不是 built-in,而是核心 MATLAB 工具箱的一部分:

>> p=which('imshow')
p =
    '/Applications/MATLAB_R2017a.app/toolbox/matlab/images/imshow.m'

imdilate是Image Processing Toolbox自带的函数:

>> p = which('imdilate')
p =
    '/Applications/MATLAB_R2017a.app/toolbox/images/images/imdilate.m'

prettyplot是我自己写的函数:

>> p = which('prettyplot')
p =
    '/Users/cris/matlab/toolbox/cris/prettyplot.m'

要区分这4种情况,首先检查返回的字符串是否以"built-in"开头,然后检查是否包含fullfile(matlabroot,'toolbox','matlab'),说明它是核心MATLAB工具箱的一部分,然后检查它是否包含fullfile(matlabroot,'toolbox'),表明它是另一个官方工具箱的一部分:

function_name = 'eig';
p = which(function_name);
if startsWith(p,'built-in')
   disp('built-in')
elseif contains(p,fullfile(matlabroot,'toolbox','matlab'))
   disp('part of core MATLAB toolbox')
elseif contains(p,fullfile(matlabroot,'toolbox'))
   disp('part of an official MATLAB toolbox')
else
   disp('not an official MATLAB function')
end

但是,请注意某些函数可能会被重载!如果您正在检查源代码以检查正在使用哪些函数,则需要知道传递的参数的类型。例如:

>> which -all eig
built-in (/Applications/MATLAB_R2017a.app/toolbox/matlab/matfun/@single/eig)  % single method
built-in (/Applications/MATLAB_R2017a.app/toolbox/matlab/matfun/@double/eig)  % double method
/Users/cris/newdip/target/dip/share/DIPimage/@dip_image/eig.m                 % dip_image method

这里可以看到有3个eig函数,如果它的输入参数是single类型就使用一个,如果是double就使用一个,如果是double就使用一个是 dip_image(自定义 class)。根据输入,使用的函数 eig 是 built-in 或第 3 方函数。

可悲的是,在您 运行 您的代码之前,您不会知道使用了哪一个。您可以手动检查输入变量有哪些值,有时很清楚。但情况并非总是如此,类型可能取决于您正在检查的函数之外的数据。

因此,收集程序使用的函数列表的最佳方法是 运行 探查器。

另一种选择:MATLAB 编译器(一个单独的产品)将收集您的函数使用的所有源 M-file,并将它们打包到一个可分发的包中。

虽然我认为基于which的解决方案更好,但为了完整起见,我们还应该考虑功能exist。来自文档:

exist name returns the type of name as a number. This list describes the type associated with each value:

  • 0 — name does not exist or cannot be found for other reasons. For example, if name exists in a restricted folder to which MATLAB® does not have access, exist returns 0.

  • 1 — name is a variable in the workspace.

  • 2 — name is a file with extension .m, .mlx, or .mlapp, or name is the name of a file with a non-registered file extension (.mat, .fig, .txt).

  • 3 — name is a MEX-file on your MATLAB search path.

  • 4 — name is a loaded Simulink® model or a Simulink model or library file on your MATLAB search path.

  • 5 — name is a built-in MATLAB function. This does not include classes.

  • 6 — name is a P-code file on your MATLAB search path.

  • 7 — name is a folder.

  • 8 — name is a class. (exist returns 0 for Java classes if you start MATLAB with the -nojvm option.)

因此,当我们在显示的示例中尝试此操作时 :

>> exist eig
ans =
     5
>> exist solve
ans =
     2
>> exist nosuchfunction
ans =
     0