我编写了一个函数来将带有通配符的mat文件加载到结构中,方法是使用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
一样加载到调用者工作区。
如何修改此函数以在调用者工作区中设置变量?
我考虑使用assignin
来执行此操作,但这意味着我首先将变量加载到函数工作区,然后将它们传输到调用者工作区。我更喜欢一种不需要两次声明变量的方法。如果不重新实施load
,这可能吗?或者,也许,将变量声明两次没有开销,因此使用assignin('caller',...)
实际上是一种有效的解决方案吗?
答案 0 :(得分:1)
当您执行该行
时S = load(varargin{:});
它会根据需要将变量作为S
或S{iFile}
的结构元素加载到文件中。如果您不想要这个,如果您只想让变量直接进入工作区,您可以跳过分配到S
load(varargin{:});
我通常更愿意避免将变量直接加载到工作区中,因为您永远无法确定文件中的变量以及它可以对工作区执行的操作。
所以作为一种替代方法,如果这是一个问题,一旦你将变量加载到S
,你就可以编写另一个通过结构的块,拉出字段名称(使用fieldnames
函数,然后在检查完成后S.(fieldname)
成员直接重新分配给fieldname
成员(使用exist(fieldname, 1)
)。
您可以使用eval
自行完成作业。请注意,在很多情况下,Mathworks最近引入了结构的动态字段引用和they recommend this eval
,但我认为这个用例(分配给字段名称命名的变量)仍然需要{{1 }}
答案 1 :(得分:0)
我确信唯一的选择是加载函数内的文件,然后使用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