Matlab 是否有相当于 Python 的 @classmethod?

问题描述 投票:0回答:2

在Matlab中,我想使用静态方法创建一个替代构造函数,并且我希望这个构造函数能够继承到子类。我没有这样做,因为我无法在静态方法中获取对 calling 类的引用。

考虑这个带有超类 A 的示例代码,它有一个替代构造函数

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

可以通过调用

A
创建
A.fromSomething()
的实例。

现在考虑子类 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( )
% 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

但是,dbstack 返回该函数定义所在的类(在本例中:

A
),而不是函数调用所在的类(在本例中,调用
B
时为
B.fromSomething()
) 。结果
B.fromSomething()
仍然会返回
A
类型的对象。

matlab static-methods
2个回答
3
投票

@classmethod
是一个非常Pythony的东西,你需要它是因为Python不做函数重载,并且不便于模拟它。在 MATLAB 中,函数具有多个签名并根据给定的输入执行不同的操作是很常见的。

我认为,您的用例是在给定特定输入

something
的情况下构造一个对象:
A.fromSomething(something)
,而不是普通的
A()
A.fromFoo(foo)

在 MATLAB 中,所有这些情况通常由同一个构造函数处理。你可以让它看起来像这样:

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

2
投票

我想说,从文档中阅读,MATLAB 似乎没有类方法:

https://uk.mathworks.com/help/matlab/matlab_oop/how-to-use-methods.html

事实上,这在大多数编程语言中并不是常见的方法类型。

© www.soinside.com 2019 - 2024. All rights reserved.