matlab - 访问特定工作区中的变量

2024-03-18

我需要类似的东西evalin,但是原来的evalinMatlab 不能递归使用。例如,我有函数 f0,它调用另外 2 个函数 f11 和 f12:

function f0()
    [v1, v2] = deal(1, 1);

    f11();
    f12();

    disp(v1);
end

函数 f11 和 f12 使用变量 v1,并且都调用函数 f2:

function f11()
    v1 = evalin('caller', 'v1');

    f2();

    assignin('caller', 'v1', v1);
end

function f12()
    v1 = evalin('caller', 'v1');

    f2();

    assignin('caller', 'v1', v1);
end

函数 f2 应该使用 f0 工作空间的变量 v1 和 v2:

function f2()
    v1 = evalin('caller', 'v1');    % get variable v1 from f11 or f12
                                    % since there is already a variable v1 
                                    % in f11 and f12's workspaces
    % TODO: get v2 from f0

    if v2 == 1
        v1 = v1 + 1;
    end

    assignin('caller', 'v1', v1);

end

无论如何,有没有办法使 TODO 成为可能而不使用v2 = evalin('caller', 'v2')在 f11 和 f12 中?


这可能是组织函数之间数据传输的最糟糕的方式之一。功能工作区分开是有充分理由的,以保持工作干净整洁。

您正试图绕过设计该语言(以及共享这种工作空间/范围分离的许多其他语言)的人所设置的所有安全措施。 Matlab 中提供了这些“旁路”函数,以便您在进行原型设计时能够准时使用。它们不适合大量使用或最终解决方案(其中大多数实际上无法编译)。

It is

  • 可能会非常令人困惑(稍后对您来说,但如果其他人必须使用您的代码,情况会更糟)。
  • 很难调试(你几乎have提前知道变量的值,以了解从另一个工作区导入是否正确)。

您在评论中说,由于变量的数量,将变量作为参数传递很复杂,但是每次您调用类似的东西时x = evalin('caller', 'x');无论如何,你必须编写一整行代码才能检索你的值。进而assignin('caller', 'x', x);是另一行代码将其发送回来......这太疯狂了。

难道不是更简单(也更短)吗?x在你的函数输入参数中? (输入 100 个变量仍然比使用 200 整行代码从不确定位置检索然后重新发送这些值要快).


推荐(如果可行):在参数中传递变量

为了使变量传递变得容易,您可以将它们全部收集在一个structure http://mathworks.com/help/matlab/structures.html (or a cell array http://mathworks.com/help/matlab/cell-arrays.html):

[v1, v2] = deal(1, 1);
myVars.v1 = v1 ;
myVars.v2 = v2 ;

myVars = f11(myVars); %// you only have one variable to pass into your functions
myVars = f12(myVars); %// just make sure you retrieve it in output too

disp(myVars.v1);

And then

function myVars = f11()
    myVars = f2(myVars);
end

依此类推,只要将变量传递给下一个函数,然后在输出中检索它,这将适用于任何级别的递归。


推荐(如果以上不可能):使用nested功能

如果你定义你的函数f11() inside your f0(),两个函数中具有相同名称的变量将被共享(在两个级别都可见)。阅读documentation http://uk.mathworks.com/help/matlab/matlab_prog/nested-functions.html#f4-73993了解更多详情。这样您就不需要多次致电evalin/assignin因为变量到处都是已知的。你的函数必须写成这样的形式:

function f0()
[v1, v2] = deal(1, 1);

f11();
f12();

disp(v1);

    function f11()
        f2();
        function f2()
            if v2 == 1
                v1 = v1 + 1;
            end
        end
    end %// END function F11

    function f12()
        f2();
        function f2()
            if v2 == 1
                v1 = v1 + 1;
            end
        end
    end %// END function F12

end %// END function F0

Stack Exchange 不会渲染它,但在 Matlab 编辑器中,您可能会注意到“共享”变量将以不同的颜色突出显示(以提醒您它们的范围与标准变量不同)。

如果我跑f0()我确实得到:

>> f0
     3

这是预期的结果。正如您所看到的,唯一的缺点是如果您打电话f2()从内部f11() and f12(), 功能f2()必须写在每个文件中(因此需要进行一些复制/粘贴)。除非在这个递归级别,您没有太多变量需要传递,所以您可以考虑编写f2()在侧面并使用标准变量传递方案。


可以工作,但不推荐

现在,如果您仍然热衷于编写大量代码来传递单个变量,那么仍然有 2 个选择:

  • use global http://mathworks.com/help/matlab/ref/global.html变量
  • use setappdata http://uk.mathworks.com/help/matlab/ref/setappdata.html and getappdata http://uk.mathworks.com/help/matlab/ref/getappdata.html

我不喜欢用global所以我这里就不详细说了。只要记住变量真的是global它必须声明为global in every函数在使用的地方。

For the appdata方法,您需要一个“容器”,您的所有功能都可以访问它。您可以使用“根”对象(标识符: 0).

例如,当你想存储一个变量时,你可以使用:

setappdata( 0 , 'v2' , v2 ) %// store the value of `v2` in a field named `'v2'` in the root object.

然后在您的任何函数中,获取值,对其进行处理,然后将其存储回来:

function f2()
    v1 = getappdata(0,'v1')     %// get the value of v1
    v2 = getappdata(0,'v2')     %// get the value of v2
    if v2 == 1
        v1 = v1 + 1;            %// modify the value of v1
    end
    v1 = setappdata(0,'v1',v1)  %// store the value of v1
end

在您的基本函数中应用相同的原则并f11(), f12()等等...只要记住在修改后始终将任何值存储回来,以便它可用于下一个需要它的函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

matlab - 访问特定工作区中的变量 的相关文章

  • 使用 varargin (...) 时如何显示不同的函数用法?

    当您输入 Matlab 函数名称并打开大括号时 例如sum 在命令窗口中 将打开一个工具提示 显示此函数的所有可能用法 当我编写自己的接受函数时varargin 工具提示仅显示一个选项 而不是varargin puts e g myfunc
  • 计算 python 字典/数组数据结构的非空尾叶 - 递归算法?

    我正在寻找一个函数来查找一种复杂字典 数组结构的所有非空端点 我认为因为我不知道嵌套数组的数量或它们的位置 所以它必须是递归的 而我只是还没有完全理解这种思维方式 所以对于嵌套字典 x top middle nested value nes
  • Matlab 的快速 JSON 解析器

    您知道 Matlab 中有一个非常快速的 JSON 解析器吗 目前我正在使用JSONlab http www mathworks com matlabcentral fileexchange 33381 jsonlab a toolbox
  • 图像增强 - 从书写中清除给定图像

    我需要清理这张照片 删除 清理我 的字样并使其变亮 作为图像处理课程作业的一部分 我可能会使用 matlab 函数 ginput 来查找图像中的特定点 当然 在脚本中您应该对所需的坐标进行硬编码 您可以使用 conv2 fft2 ifft2
  • 在 matlab/octave 中将数据集分成两个子集 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 将数据集分为两个子集 例如 训练 和 测试 其中 训练集包含 80 的数据 测试集包含剩余的 20 分裂的意思是生成一个长度等于的逻辑索引
  • 使用 python 在网络上部署 matlab 应用程序

    您好 我想使用 python 在网络上部署 matlab 应用程序 有没有办法做到这一点 我已按照数学工作网站上的文档将我的应用程序转换为 jar 文件 java 类 有人能指出我前进的正确方向吗 事实上 您的 Matlab 代码打包为 J
  • matlab矩阵中求子矩阵的通用方法

    我正在寻找一种 好 方法来在更大的矩阵 任意维数 中找到矩阵 模式 Example total rand 3 4 5 sub total 2 3 1 3 3 4 现在我希望这样的事情发生 loc matrixFind total sub 在
  • 文件/文件夹结构的递归搜索

    我正在尝试为返回文件和文件夹列表的 Web 服务构建递归搜索功能 我创建了这两个方法 因此它们充当递归搜索 它首先获取顶级内容 然后将任何文件添加到 fileList 并将任何子文件夹添加到 subFoldersList 我们传入访问级别
  • 嵌套列表递归python的序列

    给定一些数字 n 我想生成一个大小为 n 的列表 其中以下示例显示列表中的第 n 个元素应该如何 对于 n 0 返回 对于 n 1 返回 对于 n 2 返回 对于 n 3 返回 基本上 它采用先前的列表并将它们附加到新列表中 我尝试过以下方
  • 在 Matlab 中快速加载大块二进制文件

    我有一些相当大的 int16 格式的数据文件 256 个通道 大约 75 1 亿个样本 每个文件约 40 50 GB 左右 它以平面二进制格式编写 因此结构类似于 CH1S1 CH2S1 CH3S1 CH256S1 CH1S2 CH2S2
  • 是否有一个函数可以检查矩阵是否对角占优(行占优)

    矩阵是对角占优 http en wikipedia org wiki Diagonally dominant matrix 按行 如果对角线处的值在绝对意义上大于该行中所有其他绝对值的总和 对于列也是如此 只是相反 matlab中有没有函数
  • 整数的十进制表示形式中的分隔数字

    例如 我想将用户输入作为整数输入 45697 并将前两位数字存储在数组 向量或其他内容中 例如 4 5 6 9 7 这样我就可以使用一些函数调用来检查前两个值 4 5 并对它们进行计算 问题 我不知道如何存储恢复前两个值 有没有简单的函数调
  • 通过傅里叶空间填充进行插值

    我最近尝试在 matlab 上实现一个在傅立叶域中使用零填充的插值方法的简单示例 但我无法正常工作 我总是有一个小的频移 在傅里叶空间中几乎不可见 但它在时空上产生了巨大的误差 由于傅里叶空间中的零填充似乎是一种常见 且快速 的插值方法 因
  • 递归和大O

    我最近正在完成一项涉及递归和大 O 表示法的计算机科学作业 我相信我很好地理解了这一点 虽然当然不是完美的 但是有一个问题给我带来了最多的问题 奇怪的是 一看就知道是作业上最简单的一个 使用大哦符号提供最佳增长率来解决以下递归问题 T 1
  • 第99章 啤酒瓶递归好像不行

    好的 这是我在学习过程中编写的简单代码 void SingTheSong int NumOfBottles if NumOfBottles 0 printf there are simply no more bottles of beer
  • 作为动画的八度情节点

    我有以下八度脚本 TOTAL POINTS 100 figure 1 for i 1 TOTAL POINTS randX rand 1 randY rand 1 scatter randX randY hold on endfor 当我运
  • 单元格的 Fieldnames 函数的等效项

    正如标题所说 只是想知道是否有一个函数可以用作字段名 http www mathworks co uk help matlab ref fieldnames html 但适用于单元格 所以如果我有类似的东西 a imread redsqua
  • 跟踪 C++ 中递归函数被调用的次数

    我正在尝试编写一个程序 该程序具有一个参数是字符串向量的函数 我想在该函数上使用递归 但每次调用该函数时 我想更改参数 例如 fun stringArray i 其中 i 是调用该函数的次数 因此 以更简单的方式 如下所示 但我需要跟踪函数
  • 如何在Matlab中将世界坐标转换为像素索引

    我有 512x512x313 体积的 dicom 图像 并且我有一个以世界坐标表示的点 57 7475 63 4184 83 1515 我如何在 Matlab 中获得该世界坐标的相应像素坐标 我不想戳破你的幻想 但你所要求的是不可能的 我能
  • 使用 R2010b 中的符号工具箱来求解和/或 linsolve

    我前几天问了一个问题here https stackoverflow com questions 20317038 matlab linear congruence solver that supports a non prime modu

随机推荐