编写dynamicprops
的子类允许我动态地向对象添加属性:
addprop(obj, 'new_prop')
这很棒,但我也很乐意为这些属性动态创建set / get
函数。或者分析处理这些动态属性的函数。
我对Matlab的经验到目前为止,一旦我创建了一个类的实例,就不可能添加新的方法。这非常麻烦,因为我的对象可能包含大量数据,每次我想要添加新方法时都要重新加载(因为我必须做clear classes
)。
那么有没有办法即时添加方法?
答案 0 :(得分:10)
您无法添加类似添加动态属性的方法。但是,在开发过程中有两种方法可以实现新方法,不需要每次都重新加载数据。
(1)我将标准方法编写为单独的函数,并在开发期间将它们称为myMethod(obj)
。一旦我确定它们是稳定的,我就将它们的签名添加到类定义文件中 - 当然,这需要clear classes
,但它是一个延迟很长的,并且有时你可能不得不关闭无论如何,在Matlab上。
(2)使用set / get方法,事情有点棘手。如果您使用dynamicprops
添加新属性,您也可以指定他们的set / get方法,但是(很可能,这些方法/函数将希望接收属性的名称,以便他们知道要引用的内容):
addprop(obj,'new_prop');
prop = findprop(obj,'new_prop');
prop.SetMethod = @(obj,val)yourCustomSetMethod(obj,val,'new_prop')
修改强>
(2.1)这是一个如何设置隐藏属性来存储和检索结果的示例(基于jmlopez' answer)。显然,如果你能更好地了解自己的实际设计是什么,这可以得到很大改善
classdef myDynamicClass < dynamicprops
properties (Hidden)
name %# class name
store %# structure that stores the values of the dynamic properties
end
methods
function self = myDynamicClass(clsname, varargin)
% self = myDynamicClass(clsname, propname, type)
% here type is a handle to a basic datatype.
self.name_ = clsname;
for i=1:2:length(varargin)
key = varargin{i};
addprop(self, key);
prop = findprop(self, key);
prop.SetMethod = @(obj,val)myDynamicClass.setMethod(obj,val,key);
prop.GetMethod = @(obj)myDynamicClass.getMethod(obj,key);
end
end
function out = classname(self)
out = self.name_;
end
end
methods (Static, Hidden) %# you may want to put these in a separate fcn instead
function setMethod(self,val,key)
%# have a generic test, for example, force nonempty double
validateattributes(val,{'double'},{'nonempty'}); %# will error if not double or if empty
%# store
self.store.(key) = val;
end
function val = getMethod(self,key)
%# check whether the property exists already, return NaN otherwise
%# could also use this to load from file if the data is not supposed to be loaded on construction
if isfield(self.store,key)
val = self.store.(key);
else
val = NaN;
end
end
end
end
答案 1 :(得分:3)
我正在添加这个答案,因为我觉得这不直观。至少现在不是我自己。在找到这个问题后,我认为我有能够为动态类定义set / get方法所需的东西。我想要实现的只是python与__setattr__
方法的相似之处。在任何情况下,这里都是@jonas前一个类的continuation,只需要做一些修改就可以添加我们的自定义方法。
classdef myDynamicClass < dynamicprops
properties (Hidden)
name_ %# class name
end
methods
function self = myDynamicClass(clsname, varargin)
% self = myDynamicClass(clsname, propname, type)
% here type is a handle to a basic datatype.
self.name_ = clsname;
for i=1:2:length(varargin)
key = varargin{i};
addprop(self, key);
prop = findprop(self, key);
prop.SetMethod = makefunc(key, varargin{i+1});
end
end
function out = classname(self)
out = self.name_;
end
end
end
function h = makefunc(key, argtype)
h = @newfunc;
function newfunc(obj, val)
obj.(key) = argtype(val);
end
end
使用此类我将定义set方法,以便将传递给属性的参数复制到正确的类型。要了解我的意思,请考虑以下用法:
>> p_int = myDynamicClass('Point', 'x', @int8, 'y', @int32);
>> p_int.x = 1000
p_int =
myDynamicClass with properties:
y: []
x: 127
>> class(p_int.x)
ans =
int8
有了这个,我们强制x
属性是一个8位的整数,它只能保存-128到127之间的整数。还要注意每个属性的类如何给我们预期的类型。
答案 2 :(得分:1)
到目前为止,我对Matlab的经验是,一旦我创建了一个类的实例,就不可能添加新的方法。这非常麻烦,因为我的对象可能包含很多数据,每次要添加新方法时都必须重新加载这些数据(因为我必须做
clear classes
)。
对于这个问题的当今读者来说,值得注意的是,这不再是事实。 As of MATLAB R2014b在您保存类定义时,MATLAB会更新它们,并更新现有类实例的行为automatically updates accordingly。在添加新方法的情况下,这并不复杂:新方法仅可用于调用类实例,即使它们是在将方法添加到类之前创建的。
为动态属性选择设置/获取方法提供的解决方案仍然适用。
在某些情况下,您可能想向实例动态添加方法,而该方法并不构成属性设置/获取方法。我认为在这种情况下,唯一的答案就是将一个函数句柄分配给动态属性的值。这不会创建真正的方法,但是将允许您以与方法调用相同的方式调用它:
addprop(obj, 'new_method');
obj.new_method = @(varargin) my_method(obj,varargin{:});
因此,对obj.new_method(args)
的呼叫将传递到my_method
;但是,这仅适用于标量obj
;实例数组将具有new_method
属性的单独值,因此obj.new_method
不再解析为如果obj
是数组可以调用的单个函数句柄。