【问题标题】:Is there a way to push a MATLAB workspace onto a stack?有没有办法将 MATLAB 工作区推入堆栈?
【发布时间】:2023-03-27 21:30:01
【问题描述】:

有谁知道在 MATLAB 中是否可以有一堆工作区?至少可以说,这将非常方便。

我需要这个来研究。我们有几个脚本以有趣的方式交互。函数有局部变量,但没有脚本...

【问题讨论】:

  • 尽管如此出色,函数仍然是一种更好的方法。事实上,我怀疑这正是函数工作区的实现方式。

标签: matlab stack workspace


【解决方案1】:

常规的 Matlab 函数调用堆栈本身就是一个工作区堆栈。仅使用函数是使用函数的最简单方法,而 Matlab 的写时复制使这种方法相当有效。但这可能不是你要问的。

工作空间和结构之间存在自然对应关系,因为相同的标识符对变量名称和结构字段有效。它们本质上都是标识符 => Mxarray 映射。

您可以使用whosevalin 将工作区状态捕获到结构中。使用单元向量来实现它们的堆栈。 (结构数组不起作用,因为它需要同质的字段名称。)堆栈可以存储在 appdata 中以防止它出现在工作区本身中。

这里是这种技术的推送和弹出功能。

function push_workspace()

c = getappdata(0, 'WORKSPACE_STACK');
if isempty(c)
    c = {};
end

% Grab workspace
w = evalin('caller', 'whos');
names = {w.name};
s = struct;
for i = 1:numel(w)
    s.(names{i}) = evalin('caller', names{i});
end

% Push it on the stack
c{end+1} = s;
setappdata(0, 'WORKSPACE_STACK', c);


function pop_workspace()

% Pop last workspace off stack
c = getappdata(0, 'WORKSPACE_STACK');
if isempty(c)
    warning('Nothing on workspace stack');
    return;
end
s = c{end};
c(end) = [];
setappdata(0, 'WORKSPACE_STACK', c);

% Do this if you want a blank slate for your workspace
evalin('caller', 'clear');

% Stick vars back in caller's workspace
names = fieldnames(s);
for i = 1:numel(names)
    assignin('caller', names{i}, s.(names{i}));
end

【讨论】:

  • 好主意。我会试试这个!
  • 非常好!在过去,我使用 dbstop 并故意抛出错误来获得一个临时工作区来玩,但这使得它无法回答:)。
  • 如果解决了,接受怎么样?很抱歉打扰您,但这个问题在我的答案列表顶部附近,背景是可悲的非绿色。
  • 谢谢安德鲁!在过去的两年里,我已经足够多地使用它,并且在足够多的不同计算机上将它添加到我的工具箱中:github.com/ransage/matlab-utilities/tree/master/ThirdPartyTools。我根据此页面上的信息进行归因,但我欢迎改进(拉取请求或提交问题)。
【解决方案2】:

听起来您想在变量工作区之间来回切换。我能想到的最好方法是使用SAVECLEARLOAD 命令在 MAT 文件和工作区之间来回移动变量集:

save workspace_1.mat   %# Save all variables in the current workspace
                       %#   to a .mat file
clear                  %# Clear all variables in the current workspace
load workspace_2.mat   %# Load all variables from a .mat file into the
                       %#   current workspace

【讨论】:

  • 如果您将命令保存为快捷方式,这个想法可能会很有效。
  • 不过,我不想保存到磁盘。
【解决方案3】:

太棒了。 (还没有发现使用 0 和 getappdata 记录在任何地方......所以这可能在未来消失。)已将 push & pop 添加到我的 util 库中,还有以下内容:

pop_workspace(keep_current)
% keep_current:  bool:  if true, current vars retained after pop
. . .
if (~keep_current)
     evalin('caller','clear');
end

一点创意,一个人可以只保留选定的变量,并避免在流行音乐上覆盖。我发现我的工作中还需要以下功能:

function pull_workspace(names)
%   pulls variablesin cell array names{} into workspace from stack without 
%   popping the workspace stack
%
%   pulled variable will be a local copy of the stack's variable, 
%   so modifying it will leave the stack's variable untouched.
%
    if (~exist('names','var') || isempty(names))
        pull_all = true;
    else
        pull_all = false;
%           if names is not a cell array, then user gave us 
%           just 1 var name as a string.  make it a cell array.
        if (~iscell(names))
            names = {names};
        end
    end

    % Peek at last workspace on stack
    c = getappdata(0, 'WORKSPACE_STACK');
    if isempty(c)
        warning('Nothing on workspace stack');
        return;
    end
    s = c{end};

    % Stick vars back in caller's workspace
    if (pull_all)
        names = fieldnames(s);
    end
    for i = 1:numel(names)
        assignin('caller', names{i}, s.(names{i}));
    end
end

【讨论】:

    猜你喜欢
    • 2011-02-27
    • 2012-03-29
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 2013-01-04
    • 2017-03-22
    相关资源
    最近更新 更多