是否可以定义一个MATLAB类,以便可以像调用任何其他函数一样调用此类中的对象?
IOW,我问是否可以在MATLAB中编写类似以下Python类的内容:
# define the class FxnClass
class FxnClass(object):
def __init__(self, template):
self.template = template
def __call__(self, x, y, z):
print self.template % locals()
# create an instance of FxnClass
f = FxnClass('x is %(x)r; y is %(y)r; z is %(z)r')
# call the instance of FxnClass
f(3, 'two', False)
...
[OUTPUT]
x is 3; y is 'two'; z is False
谢谢!
答案 0 :(得分:5)
我不知道,MATLAB是否直接支持你想要的东西,但MATLAB确实支持一流的功能;因此,闭包可以提供可用的替代品,例如:
function f = count_call(msg)
calls = 0;
function current_count()
disp(strcat(msg, num2str(calls)));
calls = calls + 1;
end
f = @current_count;
end
在这种情况下,current_count
会关闭calls
(以及msg
)。这样你就可以表达依赖于某种内部状态的函数。你会这样使用它:
g = count_call('number of calls: ') % returns a new function ("__init__")
g() % "__call__"
答案 1 :(得分:4)
如果不在Matlab中创建java方法,我将有兴趣看看是否可行。我知道你可以做以下事情
classdef ExampleObject
properties
test;
end
methods
function exampleObject = ExampleObject(inputTest)
exampleObject.test=inputTest;
end
function f(exampleObject,funcInput)
disp(funcInput+exampleObject.test);
end
end
end
>> e=ExampleObject(5);
>> f(e,10)
15
但据我所知,如果您试图覆盖调用函数,则会遇到与Matlab的括号下标引用subsref
的冲突。你可以找到一个参考here来展示如何覆盖它,你也许可以让它做你想做的......但这似乎不是一个好的形式。不确定Matlab如何处理对象的调用(而不是函数)而不会与此混淆。
答案 2 :(得分:4)
一种方法是覆盖您班级的feval
函数:
classdef FxnClass < handle
properties
template
end
methods
function obj = FxnClass(t)
obj.template = t;
end
function out = feval(obj, varargin)
out = sprintf(obj.template, varargin{:});
end
end
end
这将用作:
>> f = FxnClass('x = %f, y = %s, z = %d');
>> feval(f, 3,'two',false)
ans =
x = 3.000000, y = two, z = 0
现在,如果您想提供额外的syntactic sugar,可以redefine为您的班级subsref
建议@Salain。将以下内容添加到上一个类定义中:
classdef FxnClass < handle
...
methods
function out = subsref(obj, S)
switch S(1).type
case '.'
% call builtin subsref, so we dont break the dot notation
out = builtin('subsref', obj, S);
case '()'
out = feval(obj, S.subs{:});
case '{}'
error('Not a supported subscripted reference');
end
end
end
end
现在你可以简单地写一下:
>> f = FxnClass('x = %f, y = %s, z = %d');
>> f(3,'two',false)
ans =
x = 3.000000, y = two, z = 0
我个人并不特别喜欢覆盖subsref
或subsasgn
函数。它们用于太多的情况,有时很难让它们写出来。例如,以下所有内容最终将使用不同的输入调用subsref
方法:
f(..)
f.template
f.template(..)
f(..).template
f(..).template(..)
还有end
关键字可能出现在索引中的情况,因此在某些情况下您可能还必须覆盖它。更不用说对象也可以连接成数组,这使得事情变得更加复杂:
>> ff = [f,f];
>> ff(1) % not what you expect!
那就是说,我认为在这种情况下@Frank建议使用带闭包的嵌套函数更优雅:
function f = FxnClass(t)
f = @call;
function out = call(varargin)
out = sprintf(t, varargin{:});
end
end
以前称之为:
>> f = FxnClass('x = %f, y = %s, z = %d');
>> f(3, 'two', false)
答案 3 :(得分:1)
如果你的意思是你想要一个类来保存一个像正常函数一样使用的方法(例如在m文件中定义),那么是的,Matlab确实支持static methods。
静态方法独立于该类的任何实例运行,实际上,您甚至不需要实例化类来使用其静态方法。
然而,Matlab不支持static fields,所以你必须首先实例化这样一个类,然后在使用函数之前设置它的字段(可能会使用这些字段,因为你问这个问题)。
鉴于静态成员的限制,您可能最好使用闭包,described by Frank。