访问 Matlab 类属性(又名常量)
Posted
技术标签:
【中文标题】访问 Matlab 类属性(又名常量)【英文标题】:Accessing Matlab Class Properties (aka Constants) 【发布时间】:2021-03-16 01:33:07 【问题描述】:我有一些类,我为其创建了几个常量属性。下面是一些示例代码:
classdef genericClassName < handle
properties (Constant)
Name = 'genericClassName'
Description = 'description of the class'
end
...
在主代码中,我通过分配类句柄来创建对象,在这种情况下,类句柄来自一个单独的函数传递的预分配值。就像
fuctionModel = @genericClassName;
稍后我将创建其他对象并将 functionModel 的值传递给这些类。到目前为止,一切正常。
Matlab documentation 表示这些常量属性的访问方式如下:
genericClassName.Name
genericClassName.Description
我可以在命令行中输入它并产生所需的结果,给出 Name 或 Description 属性的值 - 分配给常量属性的相同值.但是,我只有句柄,它在 functionModel 中保存为 @genericClassName。
这是我的问题:当我只有句柄时,如何引用这个类及其常量属性,并在前面加上它的 at 符号?
更新 缺少更简单或简洁的答案,@Edric 和@CrisLuengo 的答案组合似乎有效。例如:
mc=meta.class.fromName(func2str(functionalModel));
result = eval([mc.Name '.Description']);
将名称为Description 的常量放入变量result。这可用于我需要的东西,我可能只是将它包装到一个函数中。
【问题讨论】:
如果您要这样做,只需执行eval([func2str(functionalModel),'.Description'])
。现在您从名称中获取类描述,并且仅使用该描述来获取名称,这似乎很愚蠢。
这不仅仅是名字的问题,克里斯。这些只是示例
我的意思是,如果你不打算使用mc.PropertyList
,就不要使用mc
。 mc.Name
正是您放入mc=meta.class.fromName(...)
的字符串。您添加到问题中的代码非常多余。另外,请将其发布为答案,问题不应包含答案。如果你愿意,你可以接受你自己的答案。
重读您的评论。是的,不需要 meta.class。 func2str 提取我正在寻找的内容。
【参考方案1】:
嗯,如果您只有构造函数方法的句柄,并且您希望避免构造实例(MATLAB 允许您从实例访问 Constant
属性),那么您可以使用 meta.class.fromName
来做到这一点.
fh = @genericClassName;
% Get the metaclass from the constructor
mc = meta.class.fromName(func2str(fh));
% Find the property named 'Name'
idx = strmatch('Name', mc.PropertyList.Name)
% Get the default (Constant) value
mc.PropertyList(idx).DefaultValue
【讨论】:
谢谢,埃德里克。这很有趣。但是 Name 和 Description 属性在类定义中被分配了常量。不幸的是,这些是元属性的相同标签。当然,元属性 Name 将满足我的迫切需要。元属性 Description 在 meta.class 类文档中被描述为“当前未使用”。 不确定我是否理解问题所在。meta.class
属性“描述”与您的类的常量“描述”属性无关,它恰好具有相同的名称。您可以通过替换 strmatch
表达式中的名称来提取 any 属性的常量值,即 dIdx = strmatch('Description', mc.PropertyList.Name)
【参考方案2】:
没有类句柄之类的东西。我认为 MATLAB 中没有其他方法可以通过名称(直接在代码中或作为字符串)来引用类。你的代码
fuctionModel = @genericClassName;
在变量fuctionModel
中存储构造函数genericClassName
的句柄。使用此句柄,您可以构造类的对象,但不能做任何其他事情。这不是对类本身的引用。
目前尚不清楚您为何以这种方式设置代码。但是,通过此句柄访问常量的最简单方法是首先创建您的类的对象:
a = fuctionModel();
a.Name
Edric 提出了一个替代方案,但也不方便或漂亮。
我不提倡的第三种选择(这可能会导致代码变慢,并且难以阅读和维护)是将类的名称存储为字符串,然后使用eval
获取您的价值:
fuctionModel = 'genericClassName';
eval([fuctionModel,'.Name']);
【讨论】:
我添加了指向我提到的 Matlab 文档的链接。 (我应该把它放在第一位。)它明确表明类中定义的常量可以通过 classname-dot-propertyname 方法访问。我的问题不在于以这种方式访问常量。这是关于当我的类名带有“@”前缀时如何引用该类并实现相同的目标 - 获取命名常量属性的值。 顺便说一句,我尝试这样做的原因与 Pythonic 一致。我相信这在 Python 中是可能的,我想在这里做同样的事情,以造福给我的人。 @rahnema1:可能,是的。感谢您指出这一点! @Jim:请仔细阅读我的回答。你不能引用一个类,我认为这在 MATLAB 中根本不可能。您拥有的是其构造函数的句柄。函数只处理引用函数,没有别的。 @Jim:我一直在考虑你的用例。如果您只想传递此类引用以传递一组常量,那么您可以创建一个返回结构的函数,例如function data=foo, data=struct('Name','name','X',10);
。 MATLAB 中的常量传统上是函数,例如 pi
是一个函数。自上几个 MATLAB 版本以来,您现在可以使用 foo.Name
。这将与您的手柄完美兼容:f=@foo; f().Name
.【参考方案3】:
没有更简单或简洁的答案,@Edric 和@CrisLuengo 的答案组合似乎有效。例如:
mc=meta.class.fromName(func2str(functionalModel));
result = eval([mc.Name '.Description']);
将名称为Description 的常量放入变量result。这在包装在函数中时效果很好。
【讨论】:
以上是关于访问 Matlab 类属性(又名常量)的主要内容,如果未能解决你的问题,请参考以下文章
JVM14_Class文件结构细节魔数Class文件版本常量池访问标识(或标志)类索引|父类索引|接口索引集合字段|方法|属性表集合