如何检索的功能参数在MATLAB的名字?如何检索的功能参数在MATLAB的名字?(How do I

2019-05-13 19:30发布

除了解析功能文件,是否有一种方式来获得的输入和输出参数的名称在Matlab中的函数?

例如,假设下面的函数文件:

divide.m

function [value, remain] = divide(left, right)
     value = floor(left / right);
     remain = left / right - value;
end

从功能之外,我想要得到的输出参数,在这里一个数组: ['value', 'remain']同样的输入参数: ['left', 'right']

有没有一种简单的方法在MATLAB做到这一点? Matlab的通常似乎支持反映相当不错。

编辑背景:

这样做的目的是在一个窗口中的用户输入以呈现函数参数。 我正在写一种信号处理程序,以及函数来执行这些信号的操作都存储在一个子文件夹。 我已经有一个列表,从中用户可以选择每个函数的名称,但有些功能需要额外的参数(如平滑函数可能采取窗口大小作为参数)。

此刻,我可以添加一个新功能,该程序会发现子文件夹,用户可以选择它来执行操作。 什么我缺少的是对用户指定的输入和输出参数,在这里,我已经打了关在这里,我无法找到的函数的名称。

Answer 1:

如果您的问题被限制到要解析的简单情况函数声明行,主要功能在一个文件中(例如,你将不会被处理本地功能 , 嵌套函数或匿名函数 ),那么你就可以提取输入和输出参数的名字,因为他们使用一些标准的字符串操作,并在文件中出现 的正则表达式 。 该函数声明行有一个标准的格式,但你必须考虑到,由于一些变化:

  • 数量不等的空白或空行,
  • 的存在单行或块注释 ,和
  • 具有申报上多行打散 。

(事实证明,占据了块注释是最棘手的部分...)

我已经把一个函数get_arg_names将处理上述所有。 如果你给它的功能文件的路径,它会返回一个包含您的输入和输出参数字符串两个单元阵列(或空电池阵列,如果是没有的)。 需要注意的是可变的输入或输出列表功能将只列出'varargin''varargout' ,分别为变量名。 这里的功能:

function [inputNames, outputNames] = get_arg_names(filePath)

    % Open the file:
    fid = fopen(filePath);

    % Skip leading comments and empty lines:
    defLine = '';
    while all(isspace(defLine))
        defLine = strip_comments(fgets(fid));
    end

    % Collect all lines if the definition is on multiple lines:
    index = strfind(defLine, '...');
    while ~isempty(index)
        defLine = [defLine(1:index-1) strip_comments(fgets(fid))];
        index = strfind(defLine, '...');
    end

    % Close the file:
    fclose(fid);

    % Create the regular expression to match:
    matchStr = '\s*function\s+';
    if any(defLine == '=')
        matchStr = strcat(matchStr, '\[?(?<outArgs>[\w, ]*)\]?\s*=\s*');
    end
    matchStr = strcat(matchStr, '\w+\s*\(?(?<inArgs>[\w, ]*)\)?');

    % Parse the definition line (case insensitive):
    argStruct = regexpi(defLine, matchStr, 'names');

    % Format the input argument names:
    if isfield(argStruct, 'inArgs') && ~isempty(argStruct.inArgs)
        inputNames = strtrim(textscan(argStruct.inArgs, '%s', ...
                                      'Delimiter', ','));
    else
        inputNames = {};
    end

    % Format the output argument names:
    if isfield(argStruct, 'outArgs') && ~isempty(argStruct.outArgs)
        outputNames = strtrim(textscan(argStruct.outArgs, '%s', ...
                                       'Delimiter', ','));
    else
        outputNames = {};
    end

% Nested functions:

    function str = strip_comments(str)
        if strcmp(strtrim(str), '%{')
            strip_comment_block;
            str = strip_comments(fgets(fid));
        else
            str = strtok([' ' str], '%');
        end
    end

    function strip_comment_block
        str = strtrim(fgets(fid));
        while ~strcmp(str, '%}')
            if strcmp(str, '%{')
                strip_comment_block;
            end
            str = strtrim(fgets(fid));
        end
    end

end


Answer 2:

MATLAB提供了一种方法,以获取有关类的元数据(使用信息meta包),然而,这仅适用于OOP类不正规的功能。

一个窍门是写在飞行类的定义,它包含您想处理函数的源代码,并让MATLAB处理的源代码(这可能会非常棘手的解析如你想象:函数定义行跨越多行,实际定义之前的评论,等...)

所以你的情况创建的临时文件将如下所示:

classdef SomeTempClassName
    methods
        function [value, remain] = divide(left, right)
            %# ...
        end
    end
end

可再传给meta.class.fromName解析元数据...


这里是一个快速和肮脏实现这个技巧的:

function [inputNames,outputNames] = getArgNames(functionFile)
    %# get some random file name
    fname = tempname;
    [~,fname] = fileparts(fname);

    %# read input function content as string
    str = fileread(which(functionFile));

    %# build a class containing that function source, and write it to file
    fid = fopen([fname '.m'], 'w');
    fprintf(fid, 'classdef %s; methods;\n %s\n end; end', fname, str);
    fclose(fid);

    %# terminating function definition with an end statement is not
    %# always required, but now becomes required with classdef
    missingEndErrMsg = 'An END might be missing, possibly matching CLASSDEF.';
    c = checkcode([fname '.m']);     %# run mlint code analyzer on file
    if ismember(missingEndErrMsg,{c.message})
        % append "end" keyword to class file
        str = fileread([fname '.m']);
        fid = fopen([fname '.m'], 'w');
        fprintf(fid, '%s \n end', str);
        fclose(fid);
    end

    %# refresh path to force MATLAB to detect new class
    rehash

    %# introspection (deal with cases of nested/sub-function)
    m = meta.class.fromName(fname);
    idx = find(ismember({m.MethodList.Name},functionFile));
    inputNames = m.MethodList(idx).InputNames;
    outputNames = m.MethodList(idx).OutputNames;

    %# delete temp file when done
    delete([fname '.m'])
end

而仅仅作为运行:

>> [in,out] = getArgNames('divide')
in = 
    'left'
    'right'
out = 
    'value'
    'remain'


Answer 3:

这将是非常困难(读:不可能)一般功​​能做(想的事情就像varargin等)。 此外,在一般情况下,依靠变量名作为文件的形式可能是......不是你想要的。 我要提出一个不同的方法。

既然你控制的程序,怎么样确定各模块不仅与M文件,而且还带有额外信息的表项。 您可以记录额外的参数,函数本身,谱写当选项是布尔值之和作为复选框等

现在,放在哪里呢? 我建议有主M-file函数返回的结构,排序模块加载步骤,具有指向子功能(或嵌套函数),做实际工作的函数句柄。 这会保留单文件的设置,我敢肯定你想保留,并为你的模块更可配置的设置。

function module = divide_load()
    module.fn = @my_divide;
    module.name = 'Divide';
    module.description = 'Divide two signals';
    module.param(1).name = 'left';
    module.param(1).description = 'left signal';
    module.param(1).required_shape = 'columnvector';
    % Etc, etc.

    function [value, remain] = my_divide(left, right)
         value = floor(left / right);
         remain = left / right - value;
    end
end


Answer 4:

当你不能从有关的内容进行了编程的langauge获取信息(例如,“反思”),你有步骤的语言之外。

另一个海报建议“正则表达式”,当应用到真正的解析程序,因为正则表达式无法分析上下文无关汉语语言总是失败。

为了可靠地做到这一点,你需要一个真正的M语言解析器,这将让您使用解析树。 那么这是相当容易的。

我们的DMS软件再造工具包具有可用于它的M语言解析器,并能做到这一点。



Answer 5:

你有没有考虑使用地图容器?

你可以沿着这些路线写你的函数。 。 。

function [outMAP] = divide(inMAP)
     outMAP = containers.Map();
     outMAP('value') = floor(inMAP('left') / inMAP('right'));
     outMAP('remain') = inMAP('left') / inMAP('right') - outMAP('value');
end

...并呼吁他们这样的...

inMAP  = containers.Map({'left', 'right'}, {4, 5});
outMAP = divide(inMAP);

...然后简单地使用下面的语法检查塔的变量名...

>> keys(inMAP)

ans = 

    'left'    'right'


Answer 6:

inputname(argnum) http://www.mathworks.com/help/techdoc/ref/inputname.html 。



文章来源: How do I retrieve the names of function parameters in matlab?