我写了一个函数,将垫子中带有通配符的垫子加载到结构中,使用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