You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MATLAB中通过字符串获取Simulink.Parameter对象句柄(禁用eval())

一、从变量名字符串获取对象句柄

你可以利用MATLAB的工作区访问能力,替代不安全且不够优雅的eval()。这里提供两种封装好的实现,既能安全获取对象,还能做类型校验:

方法1:用evalin实现(轻量简洁)

function objects = get_object_handles_from_string(varnames)
    objects = cell(size(varnames));
    % 遍历每个变量名字符串
    for idx = 1:numel(varnames)
        varName = varnames{idx};
        try
            % 从基础工作区直接获取变量,避免eval的安全风险
            currentVar = evalin('base', varName);
            % 校验是否为Simulink.Parameter类型
            if isa(currentVar, 'Simulink.Parameter')
                objects{idx} = currentVar;
            else
                warning('变量 %s 不是Simulink.Parameter对象,已跳过', varName);
                objects{idx} = [];
            end
        catch err
            warning('获取变量 %s 失败:%s', varName, err.message);
            objects{idx} = [];
        end
    end
end

方法2:面向对象的工作区操作(更规范)

function objects = get_object_handles_from_string(varnames)
    objects = cell(size(varnames));
    baseWS = matlab.workspace.Workspace('base');
    for idx = 1:numel(varnames)
        varName = varnames{idx};
        if baseWS.exists(varName)
            currentVar = baseWS.getVariable(varName);
            if isa(currentVar, 'Simulink.Parameter')
                objects{idx} = currentVar;
            else
                warning('变量 %s 不是Simulink.Parameter对象,已跳过', varName);
                objects{idx} = [];
            end
        else
            warning('变量 %s 不存在于基础工作区', varName);
            objects{idx} = [];
        end
    end
end

使用方式完全符合你的预期:

varnames = {'var1','var2'};
objects = get_object_handles_from_string(varnames);
value_1 = objects{1}.Value(:);

二、从对象反向获取变量名

由于Simulink.Parameter是值类对象(而非句柄类),无法直接通过对象本身关联到工作区的变量名,我们需要遍历工作区变量并匹配核心属性:

function varName = get_varname_from_object(targetObj)
    % 输入类型校验
    if ~isa(targetObj, 'Simulink.Parameter')
        error('输入必须是Simulink.Parameter对象');
    end
    varName = '';
    baseWS = matlab.workspace.Workspace('base');
    allVarNames = who('base');
    
    % 遍历工作区所有变量,匹配目标对象
    for idx = 1:numel(allVarNames)
        currentName = allVarNames{idx};
        currentVar = baseWS.getVariable(currentName);
        % 对比核心属性确保是同一个对象
        if isa(currentVar, 'Simulink.Parameter') && ...
           isequal(currentVar.Value, targetObj.Value) && ...
           isequal(currentVar.Min, targetObj.Min) && ...
           isequal(currentVar.Max, targetObj.Max) && ...
           isequal(currentVar.DataType, targetObj.DataType)
            varName = currentName;
            break; % 工作区变量名唯一,找到即退出
        end
    end
    
    if isempty(varName)
        warning('基础工作区中未找到匹配的Simulink.Parameter对象');
    end
end

使用示例:

% 假设objects{1}是已获取的Simulink.Parameter对象
name = get_varname_from_object(objects{1});
disp(name); % 输出对应的变量名,比如'var1'

为什么你之前尝试的方法不生效?

  • whos:只能获取变量的元数据(类型、大小等),无法直接拿到对象本身;
  • inputname:仅能返回函数直接输入参数的变量名,对元胞数组里的对象无效;
  • str2func:用于生成函数句柄,和变量访问完全是两个场景;
  • findobj:仅适用于句柄类对象的查找,而Simulink.Parameter是值类,所以无法用这个方法。

内容的提问来源于stack exchange,提问作者I. Amon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:04:32