英文:
Is there a Matlab equivalent to Pythons @classmethod?
问题
在Matlab中,我想使用静态方法创建一个替代构造函数,并希望这个构造函数能够在子类中继承。我失败了,因为我无法在静态方法内部获取对调用类的引用。
考虑以下示例代码,其中有一个具有替代构造函数fromSomething的超类A:
classdef A
properties
a
end
methods
function obj = A(a)
if nargin
obj.a = a;
end
end
end
methods(Static)
function obj = fromSomething()
obj = A(42);
end
end
end
可以通过调用A.fromSomething()来创建A的一个实例。
现在考虑子类B:
classdef B < A
methods
function someFunctionality(obj)
end
end
end
调用B.fromSomething()会返回一个类型为A的对象。这不是期望的行为。如何修改这段代码,使得B.fromSomething()可以返回一个类型为B的对象,并且代码复用尽可能少?
在Python中,可以使用@classmethod装饰器来实现:
from dataclasses import dataclass
@dataclass
class A:
a : float
@classmethod
def from_something(cls):
return cls(42)
class B(A):
def some_functionality(self):
...
请注意,在Python代码中,B.from_something()将返回一个类型为B的对象。
我尝试过使用dbstack来获取当前类的类名:
...
function obj = fromSomething()
cls = currentClass();
obj = feval(cls.Name, 42);
end
...
function [ cls, str ] = currentClass( )
% 参考自:https://nl.mathworks.com/matlabcentral/answers/77387-any-way-to-get-the-current-class
dbk = dbstack( 1, '-completenames' );
if isempty( dbk )
str = 'base';
else
str = dbk(1).name;
end
cac = regexp( str, '\.', 'split' );
switch numel( cac )
case 1
case 2
cls = meta.class.fromName( cac{1} );
str = cac{2};
case 3
otherwise
end
end
然而,dbstack返回的是函数所定义的类(在本例中是A),而不是函数所调用的类(在本例中是调用B.fromSomething()时的B)。因此,B.fromSomething()仍然会返回一个类型为A的对象。
英文:
In Matlab, I want to create an alternative constructor using a static method, and I want this constructor to be able to inherit to subclasses. I fail to do so, because I cannot get a reference to the calling class inside a static method.
Consider this example code with superclass A that has an alternative constructor fromSomething:
classdef A
properties
a
end
methods
function obj = A(a)
if nargin
obj.a = a;
end
end
end
methods(Static)
function obj = fromSomething()
obj = A(42);
end
end
end
An instance of A can be created by calling A.fromSomething().
Now consider subclass B:
classdef B < A
methods
function someFunctionality(obj)
end
end
end
Calling B.fromSomething() gives an object of type A. That is not the desired behavior. How can this code be changed such that B.fromSomething() gives me an object of type B with minimal code re-use?
In Python, this would be done using a @classmethod decorator.
from dataclasses import dataclass
@dataclass
class A:
a : float
@classmethod
def from_something(cls):
return cls(42)
class B(A):
def some_functionality(self):
...
Note that in the Python code B.from_something() will return an object of type B.
I've tried to obtain the class name of the current class using dbstack:
...
function obj = fromSomething()
cls = currentClass();
obj = feval(cls.Name, 42);
end
...
function [ cls, str ] = currentClass( )
% Taken from https://nl.mathworks.com/matlabcentral/answers/77387-any-way-to-get-the-current-class
dbk = dbstack( 1, '-completenames' );
if isempty( dbk )
str = 'base';
else
str = dbk(1).name;
end
cac = regexp( str, '\.', 'split' );
switch numel( cac )
case 1
case 2
cls = meta.class.fromName( cac{1} );
str = cac{2};
case 3
otherwise
end
end
However, dbstack returns the class that the function is defined on (in this case: A), rather than the class the function is called on (in this case, B when calling B.fromSomething()). As a result B.fromSomething() will still return an object of type A.
答案1
得分: 2
根据文档,我会说MATLAB似乎没有类方法:
https://uk.mathworks.com/help/matlab/matlab_oop/how-to-use-methods.html
事实上,这在大多数编程语言中都不是常见的方法类型。
英文:
I would say that reading from the docs, MATLAB does not seem to have class methods:
https://uk.mathworks.com/help/matlab/matlab_oop/how-to-use-methods.html
In fact this is not a common type of method in most programming languages.
答案2
得分: 2
@staticmethod 是一种非常具有 Python 风格的东西,你需要它是因为 Python 不支持函数重载,而且不容易模拟它。在 MATLAB 中,一个函数通常可以有多个签名,根据给定的输入执行不同的操作。
我理解你的用例是根据特定输入 something 构建一个对象:A.fromSomething(something),而不是一个普通的 A() 或 A.fromFoo(foo)。
在 MATLAB 中,所有这些情况通常由同一个构造函数处理。你可以让它看起来像这样:
classdef A
% ...
methods
function obj = A(arg)
if nargin == 0
% 情况 A()
else
if isa(arg, 'Something')
% 情况 A(something)
elseif isa(arg, 'Foo')
% 情况 A(foo)
else
error('非法输入')
end
end
end
end
end
英文:
@staticmethod is a very Pythony thing, and you need it because Python doesn't do function overloading, and doesn't make it easy to simulate it. In MATLAB it is quite common for a function to have multiple signatures, and do different things depending on which inputs are given.
Your use case, I presume, is to construct an object given a specific input something: A.fromSomething(something), as opposed to a plain A(), or a A.fromFoo(foo).
In MATLAB all these cases are typically handled by the same constructor. You can make it look like this:
classdef A
% ...
methods
function obj = A(arg)
if nargin == 0
% case A()
else
if isa(arg, 'Something')
% case A(something)
elseif isa(arg, 'Foo')
% case A(foo)
else
error('Illegal input')
end
end
end
end
end
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论