如何获取从句柄到 Matlab 中方法的输出数量?
Posted
技术标签:
【中文标题】如何获取从句柄到 Matlab 中方法的输出数量?【英文标题】:How to get the number of outputs from a handle to a method in Matlab? 【发布时间】:2017-05-11 23:35:12 【问题描述】:您可以使用函数句柄调用对象的方法。示例:
classdef foo
methods
function value=foofun(this)
value=1;
end
end
end
然后
fun=@foofun;
fun(foo);
我猜句柄只是一个字符串,它不会打扰Matlab,它在使用句柄之前无法判断哪个函数是预期的。如果使用不同类型的对象作为第一个参数,甚至可以使用相同的句柄来调用不同的方法。
要捕获函数的输出,您可以这样做:
outputs=cell(numberOfOutputs,1);
[outputs:]=fun(foo);
但是,如果函数句柄是代码中的一个参数,那么输出的数量就是一个问题。对于普通函数的句柄,nargout 可以解决这个问题,但现在 nargout 无能为力,因为句柄不能自行确定将调用哪个函数。 nargout 需要第二个输入,即要使用的对象的类型。
同时需要句柄和输出数量作为参数有点不雅。是否有另一种方法可以间接调用方法并仍然捕获所有输出?
用例
想象一个有节点和节点之间的边的图。每条边都有一些与该特定边相关的数据对象。我有兴趣对这些数据对象进行各种计算。
示例
获取与特定边缘关联的所有数据对象并计算这些对象的光谱。 使用每个边缘中最漂亮的数据对象并从这些对象中获取光谱。 随机选择十条边,从每条边中随机选择一个数据对象,然后将这些对象与一个特定的单独对象进行比较。设计
这个想法是将对象的选择和计算分成不同的功能。这样,用户可以将任何计算与任何选择方法结合起来。每次向数据对象添加新方法时,已经可以与现有的对象选择方法一起调用,每次添加新的选择方法时,都可以与所有可用的计算方法一起使用。
我当前使用的函数的简化版本如下所示
function [ outs ] = callForEach(objects, fun, numberOfOutputs, extraArguments)
for ii=1:length(objects)
out=cell(1,numberOfOutputs);
[out:]=fun(objectsii,extraArgumentsii,:);
outs(ii,:)=out;
end
end
我希望能够避免参数 numberOfOutputs。这给用户带来了不便,而且这样做更容易出错。
我想我可以为每个方法强制使用相同的接口:如果他们需要多个输出,每个人都会返回一个元胞数组。然后我可以将该单元格数组或返回的任何内容分配到单个单元格中。但是,所有内置函数似乎都更喜欢使用多个输出,因此至少存在风格上的差异。如果我想使用其中一个内置函数作为句柄,我需要编写一个包装器以使内置函数符合接口。
【问题讨论】:
这个的预期用例是什么?通常,当库函数需要一个函数句柄并指定句柄必须匹配的预期接口时,需要通过函数句柄进行间接调用(例如,ode45
的odefun
和可选的Events
句柄)。传递类实例并直接对其进行操作会更容易。
编辑回答了我的大部分问题,除了“手柄的预期界面是什么?”我看到@prettiest
应该采用edges
的数组并返回最漂亮的数组;并且@spectrum
应该对dataObjects
的数组进行操作并返回关联的sepctra 数组。多个输出在哪里?
我实际上认为@spectrum 只对单个对象进行操作,因此调用它的人可以决定是否并行化调用。但是,这种差异并不重要。
我仍然不知道未知数量的输出在哪里起作用。此外,您是否打算让用户访问绑定到这些正在播放的对象的这套方法?如果是这样,您可以根据this.(nameOfMethod)(x);
之类的字符串动态调用它们,并可能用用户定义的方法字符串替换对句柄的需求。
对不起,我不明白缺少什么。 :D 方法集自然绑定到游戏中的对象,它们是方法(类的成员),而不是函数。 this.(nameOfMethod)(x)
我猜是另一种选择,但我认为这没有什么不同。方法的签名不同,所以我不知道我应该尝试捕获多少返回。
【参考方案1】:
检查这个类为foo.m
。通过运行foo.main()
,您可以恢复大部分已解决的问题。
这不是 OOP 中最大的优雅,但你有 Matlab。
记住obj
变量是MANDATORY,进出。没有obj
,没有点花哨。
最后的调用,必须包含f1
。放置~
不仅失去了花哨,还失去了对象及其数据。
除了obj
处理之外,nargin
|nargout
|varargin
|varargout
仅在函数体内有效,并且与往常一样取决于运行时。人们一般无法知道你会抛出多少参数,因为它相当于可变参数单元格的长度。
classdef foo
properties
value;
end
methods
function [obj,flag]=fun1(obj,this)
obj.value=this+1;
flag=1;
end
function [obj,flag]=fun2(obj,this)
obj.value=2*this;
flag=2;
end
function [obj,varargout]=fun3(obj,varargin)
for i=1:nargin-1
varargouti=varargini;
end
obj.value=0;
end
end
methods (Static)
function main()
if 0
%% Run this line
foo.main()
end
f1=foo();
[f1,flag]=f1.fun1(10);
flag
f1.value
f=@fun2;
%[f1,flag]=f1.f(10); % fails
flag
f1.value
[f1,flag]=f1.('fun2')(10);
flag
f1.value
[~,flag]=f1.fun2(10); % fails
flag
f1.value
[f1,a1,a2,a3,a4]=f1.fun3('x1',2,[],@(x)(x>1))
end
end
end
【讨论】:
以上是关于如何获取从句柄到 Matlab 中方法的输出数量?的主要内容,如果未能解决你的问题,请参考以下文章