【问题标题】:Matlab method as a propertyMatlab方法作为属性
【发布时间】:2019-05-22 07:43:58
【问题描述】:

有没有办法编写一个具有自己的方法之一作为属性的 Matlab 类?我正在编写模拟代码,其中类的方法(实际上是一个物理方程)可能会在未来的发展中发生变化,所以我希望存档的类实例包含该方法。

这是一些类似于 Matlab 的伪代码。

classdef foo
   properties
      bar % some property
      baz % a property that contains the method baz
   end
   methods
       function out = baz() % the method I want to store
          stuff
       end
   end
end

请注意,我希望“东西”以某种方式存储为属性,因此当我保存实例时,我会知道我使用的方法的版本。

最好是公共的,而不是静态属性。我想序列化实例。

【问题讨论】:

  • 您的意思是属性中的方法reference(即函数句柄)?请提供一些伪代码(或另一种语言的代码),以显示您想要实现的确切目标以及以后如何使用它。我还要提到需要什么样的属性和方法属性(privatestaticconst 等)
  • @Dev-iL 我不认为我的意思是方法参考。我实际上想存储方法的内容,而不仅仅是它的句柄。我是使用 Matlab 作为面向对象语言的新手,而且总体上仍然是 OOL 编程的业余爱好者,所以我的术语可能并不缺乏。我会尝试写一些伪代码来解释得更透彻。
  • 可以添加“类版本”之类的属性并记录类本身之外的内容。然而,它是独立的,有一定的清洁度。
  • 所以基本上你想在类的某些属性中以纯文本形式保存类定义(或它的一部分)?我必须说这在 OOP 中并不常见。
  • @Rico 您应该从问题中删除此添加并将其作为答案发布(因为它似乎可以解决您的问题,而不是澄清它)。顺便说一句,我认为编写一些接受文件名和函数/方法名并且只返回函数代码的函数可能是值得的。

标签: matlab object methods


【解决方案1】:

如果您的函数是单个表达式,则可以使用匿名函数。 It will be saved to a MAT-file(感谢 gnovice 指出这一点)。比如:

classdef foo
   properties
      bar = 0
      baz = @(x)sqrt(x)
   end
end

现在我可以做:

f = foo;
f.baz(2)  % returns 1.4142
save foo_test f
clear

然后将foo.mbaz的定义改为baz = @(x)x.^2,然后:

f2 = foo;
f2.baz(2) % returns 4
load foo_test
f.baz(2)  % still returns 1.4142
f2.baz(2) % still returns 4

如果你有更复杂的功能,你可以这样设置:

classdef foo
   properties
      bar = 5
      baz_func = @(obj,x) baz_2019_05_22(obj,x) % could be private
   end
   methods
      function out = baz(obj,x)
         out = obj.baz_func(obj,x);
      end
      function out = baz_2019_05_22(obj,x) % could be private
         out = obj.bar * sqrt(x);
      end
   end
end

现在:

f = foo;
f.baz(2) % returns 7.0711
save foo_test f
clear

将来您会更改函数,但保留代码并创建一个新的(私有)函数来执行计算:

classdef foo
   properties
      bar = 5
      baz_func = @(obj,x) baz_2022_08_04(obj,x) % could be private
   end
   methods
      function out = baz(obj,x)
         out = obj.baz_func(obj,x);
      end
      function out = baz_2019_05_22(obj,x) % could be private
         out = obj.bar * sqrt(x);
      end
      function out = baz_2022_08_04(obj,x) % could be private
         out = obj.bar * x.^2;
      end
   end
end

这里的困难是保留旧代码而不更改它...但是您可以在此处使baz 函数尽可能复杂。现在:

f2 = foo;
f2.baz(2) % returns 20
load foo_test
f.baz(2)  % still returns 7.0711

【讨论】:

  • 这很聪明!它有效地服务于我的目的,但它确实需要在开发中保持警惕——如果不推荐使用的方法被删除,我相信你的最后声明 f.baz(2) 会抛出一个错误(未定义的方法)。不过,考虑到所有因素,这并不是一个糟糕的失败方式。但是,如果在不更改名称的情况下更改方法,我们将回到不知道旧方法的状态,甚至不知道有一个。 +1,但我会在接受之前等待,因为另一种解决方案可能仍会缓解这些限制。
  • @Rico:是的,您需要保留旧代码。需要建立良好的编程实践,包括一个代码修订工具,以便在出现问题时能够返回到旧版本的代码。不幸的是,没有办法将函数存储在 MAT 文件中,除了限于单个表达式的匿名函数。
  • @Rico:也许有一种方法可以将 M 文件作为文本存储在对象中,并在调用之前将其写入文件。这不会是高性能的,但它可能是用你的对象存储代码的最安全的方式。也许如果我以后有时间我会玩这个想法并发布另一个答案。 :)
  • 哈!当我在原始问题的 cmets 中吐出类似的内容时,您输入了最后一条评论。我认为使用这种方法是有道理的,尤其是在进行科学计算时,可重复性和透明性是其优点。感谢您考虑额外的答案:)
  • 我相信我已经实现了我们在我的 OP 编辑​​中讨论的内容。无论如何我都会接受你的回答,因为它提供的信息最多。
【解决方案2】:

根据 Dev-iL 的评论和 Cris 的回答,这就是我所做的,它将整个 classdef 文件作为纯文本存储在属性 class_definition 中。

classdef foo
   properties
      class_definition
   end
   methods
       function obj = foo()
         obj.class_definition = fileread([mfilename(),'.m']);
       end
       function out = baz() % the method I want to store
          stuff
       end
   end
end

正如 Dev-iL 建议的那样,编写一个接受文件名和函数/方法句柄并将该函数的代码(而不是整个 classdef 文件)作为纯文本返回的函数可能会更好地回答原始问题,所以我'将接受这样的答案,如果它被张贴。这个解决方案对我的目的来说已经足够了。

【讨论】:

    【解决方案3】:
    classdef foo
        properties (Dependent, SetAccess = 'private')
            baz % a property that contains the method baz
        end
        methods
           function out = bazMethod() % the method I want to store
              stuff
           end
    
           function bazOut = get.baz(self)
               bazOut = bazMethod();
           end
        end
    
    end
    

    它不会序列化当前的方法定义 bazMethod,但如果你想要的只是定义,听起来你想要 baz 成为一个 Dependent 属性。

    【讨论】:

    • 谢谢。我想对其进行序列化......有没有办法做到这一点而不将baz设为私有?很聪明,你所做的……接近我需要的。
    猜你喜欢
    • 2012-09-10
    • 1970-01-01
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    相关资源
    最近更新 更多