MATLAB负载垫子用通配符(*)进入当前工作区



我写了一个函数,将垫子中带有通配符的垫子加载到结构中,使用dir捕获通配符,然后调用load。这是功能:

function S = loadw(varargin)
%LOADW Load variables from file into workspace, with wildcard (*) in file name
filename = varargin{1};
if(ismember('*', filename))
    [pathstr, ~, ext] = fileparts(filename);
    if(isempty(pathstr))
        pathstr = '.';
    end
    if(~strcmp(ext, '.mat'))
        filename = [filename '.mat'];
    end
    dirFiles = dir(filename);
    if(isempty(dirFiles))
        error(['Unable to read file ''' filename ''': no such file or directory.']);
    elseif(numel(dirFiles) == 1)
        varargin{1} = [pathstr filesep dirFiles(1).name];
        S = load(varargin{:});
    else
        S = cell(numel(dirFiles), 1);
        for iFile = 1:numel(dirFiles)
            varargin{1} = [pathstr filesep dirFiles(iFile).name];
            S{iFile} = load(varargin{:});
        end
    end
else
    S = load(varargin{:});
end

这效果很好,但是它只能像load那样将文件加载到结构中,而不能像CC_3一样加载到呼叫者工作区中。如何修改此功能以在呼叫者工作区中设置变量?

我考虑使用assignin来执行此操作,但这意味着我首先将变量加载到函数工作区中,然后将它们传输到呼叫者工作区。我更喜欢一种不需要两次声明变量的方法。这是否可以不重新实现load?或者,也许在两次声明变量时没有开销,因此使用assignin('caller',...)实际上是一个有效的解决方案?

执行行

S = load(varargin{:});

它将作为S的结构元素或S{iFile}的结构元素加载变量。如果您不想要这个,如果您只希望变量直接进入工作区,则可以跳过分配到S

load(varargin{:});

我通常更喜欢避免将变量直接加载到工作区中,因为您永远无法确定文件中有哪些变量以及对工作空间的作用。

因此,作为一种替代方法,如果这是一个问题,一旦将变量加载到S中,您就可以编写另一个通过结构的块,拔出字段名称(使用fieldnames函数),然后再重新打印S.(fieldname)成员直接在检查工作空间中尚不存在(使用exist(fieldname, 1))之后。

您将使用eval进行任务本身。请注意,Mathworks最近引入了构造的动态字段引用,他们在很多情况下都建议通过eval进行此建议,但我认为此用例(分配给字段名称为字段名称命名的变量)仍然要求eval

我坚信,唯一的选项是将文件加载到功能中,然后使用assignin('caller',...),或使用evalin('caller', 'load(...);')。在这些之间,我选择了后者,因为我认为避免声明变量两次符合eval功能的缺点。这是我的功能:

function S = loadw(varargin)
%LOADW Load variables from file into workspace, with wildcard (*) in file name
filename = varargin{1};
if(ismember('*', filename))
    [pathstr, ~, ext] = fileparts(filename);
    if(isempty(pathstr))
        pathstr = '.';
    end
    if(~strcmp(ext, '.mat'))
        filename = [filename '.mat'];
    end
    dirFiles = dir(filename);
    if(isempty(dirFiles))
        error(['Unable to read file ''' filename ''': no such file or directory.']);
    elseif(numel(dirFiles) == 1)
        varargin{1} = [pathstr filesep dirFiles(1).name];
        if(nargout > 0)
            S = load(varargin{:});
        else
            strLoadCommand = ['load(''' strjoin(varargin, ''', ''') ''');'];
            evalin('caller', strLoadCommand);
        end
    else
        if(nargout > 0)
            S = cell(numel(dirFiles), 1);
        end
        for iFile = 1:numel(dirFiles)
            varargin{1} = [pathstr filesep dirFiles(iFile).name];
            if(nargout > 0)
                S{iFile} = load(varargin{:});
            else
                strLoadCommand = ['load(''' strjoin(varargin, ''', ''') ''');'];
                evalin('caller', strLoadCommand);
            end
        end
    end
else
    if(nargout > 0)
        S = load(varargin{:});
    else
        strLoadCommand = ['load(''' strjoin(varargin, ''', ''') ''');'];
        evalin('caller', strLoadCommand);
    end
end

最新更新