英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论