2012-08-08 9 views
9

pisanie podklasę dynamicprops pozwala mi dodać właściwości dynamicznie do obiektu:czy można dodawać metody w locie do zajęć matlab (programowanie obiektowe)?

addprop(obj, 'new_prop') 

to jest super, ale chciałbym również uwielbiają tworzyć set/get funkcje dla tych właściwości w locie. Lub funkcje analizy, które działają na tych właściwościach dynamicznych.

Moje doświadczenie z Matlabem było tak duże, że po utworzeniu instancji klasy dodanie nowych metod nie jest możliwe. Jest to bardzo uciążliwe, ponieważ mój obiekt może zawierać wiele danych, które będę musiał ponownie załadować za każdym razem, gdy chcę dodać nową metodę (ponieważ muszę wykonać clear classes).

Czy istnieje sposób dodawania metod w locie?

+0

Możesz dodawać nowe metody, o ile później wyczyścisz klasy, ale chcesz je obejść. Nie sądzę, że to będzie działać ogólnie. –

Odpowiedz

10

Nie można dodawać metod takich jak właściwości dynamiczne. Istnieją jednak dwa sposoby wdrażania nowych metod podczas projektowania, które nie wymagają ponownego ładowania danych za każdym razem.

(1) Piszę standardowe metody jako oddzielne funkcje i wywołuj je jako myMethod(obj) podczas programowania. Kiedy jestem pewien, że są stabilne, dodałem ich sygnaturę do pliku definicji klasy - to oczywiście wymaga clear classes, ale jest to dużo opóźnione i od czasu do czasu może być konieczne wyłączenie Matlaba. .

(2) Metody ustawiania/pobierania sprawiają, że niektóre czynności są nieco trudniejsze. Jeśli używasz dynamicprops do dodawania nowych właściwości, możesz również określić ich metody ustawiania/pobierania (najprawdopodobniej te metody/funkcje będą chciały otrzymać nazwę właściwości, aby wiedziały, do czego się odnoszą):

addprop(obj,'new_prop'); 
prop = findprop(obj,'new_prop'); 
prop.SetMethod = @(obj,val)yourCustomSetMethod(obj,val,'new_prop') 

EDIT

(2,1) Oto przykład jak skonfigurować ukryty obiekt do przechowywania i pobierania wyników (w oparciu o jmlopez' answer). Oczywiście może to być o wiele lepsze, jeśli masz lepszy pomysł, co masz faktycznie projektowania

classdef myDynamicClass < dynamicprops 
    properties (Hidden) 
     name %# class name 
     store %# structure that stores the values of the dynamic properties 
    end 
    methods 
     function self = myDynamicClass(clsname, varargin) 
      % self = myDynamicClass(clsname, propname, type) 
      % here type is a handle to a basic datatype. 
      self.name_ = clsname; 
      for i=1:2:length(varargin) 
       key = varargin{i}; 
       addprop(self, key); 
       prop = findprop(self, key); 
       prop.SetMethod = @(obj,val)myDynamicClass.setMethod(obj,val,key); 
       prop.GetMethod = @(obj)myDynamicClass.getMethod(obj,key); 
      end 
     end 
     function out = classname(self) 
      out = self.name_; 
     end 
    end 
    methods (Static, Hidden) %# you may want to put these in a separate fcn instead 
     function setMethod(self,val,key) 
      %# have a generic test, for example, force nonempty double 
      validateattributes(val,{'double'},{'nonempty'}); %# will error if not double or if empty 

      %# store 
      self.store.(key) = val; 

     end 
     function val = getMethod(self,key) 
      %# check whether the property exists already, return NaN otherwise 
      %# could also use this to load from file if the data is not supposed to be loaded on construction 
      if isfield(self.store,key) 
       val = self.store.(key); 
      else 
       val = NaN; 
      end 
     end 
    end 
end 
+0

, więc 'myMethod' będzie w rzeczywistości ogólną funkcją (a nie metodą klasową), którą możesz zmienić w dowolny sposób, prawda? – memyself

+1

@memyself: dokładnie. Następnie możesz albo skopiować 'myMethod' do pliku classdef, albo po prostu dodać podpis do pliku classdef i przenieść' myMethod' do folderu klasy. – Jonas

+0

to fajna sztuczka - nigdy o tym nie myślałem! – memyself

3

Dodaję tę odpowiedź, ponieważ myślę, że to nie jest intuicyjne. Przynajmniej nie w tej chwili dla siebie. Po znalezieniu tego pytania pomyślałem, że mam to, czego potrzebowałem, aby móc zdefiniować metody ustawiania/pobierania dla mojej klasy dynamicznej. Wszystko, co chciałem osiągnąć, było podobne do tego, co python robi z jego metodą __setattr__. W każdym razie tutaj jest continuation z klasy wykonanej przez @jonas jakiś czas temu z kilkoma modyfikacjami, aby dodać naszą niestandardową metodę ustawiania.

classdef myDynamicClass < dynamicprops 
    properties (Hidden) 
     name_ %# class name 
    end 
    methods 
     function self = myDynamicClass(clsname, varargin) 
      % self = myDynamicClass(clsname, propname, type) 
      % here type is a handle to a basic datatype. 
      self.name_ = clsname; 
      for i=1:2:length(varargin) 
       key = varargin{i}; 
       addprop(self, key); 
       prop = findprop(self, key); 
       prop.SetMethod = makefunc(key, varargin{i+1}); 
      end 
     end 
     function out = classname(self) 
      out = self.name_; 
     end 
    end 
end 

function h = makefunc(key, argtype) 
    h = @newfunc; 
    function newfunc(obj, val) 
     obj.(key) = argtype(val); 
    end 
end 

Z tej klasie mam określającej metodę tak ustawiona, że ​​parametr przekazany do atrybutu jest kopiowany do właściwego typu. Aby zobaczyć, co mam na myśli rozważyć następujący Zastosowanie:

>> p_int = myDynamicClass('Point', 'x', @int8, 'y', @int32); 
>> p_int.x = 1000 

p_int = 

    myDynamicClass with properties: 

    y: [] 
    x: 127 

>> class(p_int.x) 

ans = 

int8 

Dzięki temu jesteśmy zmuszeni atrybut x być liczbą całkowitą z 8 bitów, która może pomieścić tylko liczby całkowite od -128 do 127. Również zauważyć, jak każda klasa atrybut podaje nam zamierzony typ.

+1

To jest poprawne. Zwróć uwagę, że podczas definiowania niestandardowych metod ustawiania/pobierania możesz napotkać ryzyko nieskończonych rekursji, ponieważ analizator składni Matlab nie zawsze będzie wiedział, jak uniknąć wywoływania metody set podczas przypisywania wartości właściwości. Aby ułatwić sobie życie (również w celu debugowania), pomocne może być posiadanie ukrytej właściwości do przechowywania wartości, do której dostęp mają metody getter/setter. – Jonas

+1

@Jonas świetny komentarz - czy mógłbyś bardziej szczegółowo opisać ukrytą własność i jak ją wdrożyć? – memyself

+0

@ Jonas, tak podobny do zmiennej python '__dict__'. Wspominają o możliwości nieskończonej rekursji [tutaj] (http://docs.python.org/2/reference/datamodel.html#object.__setattr__). Czy istnieje jakaś dokumentacja dotycząca programu Matlab, która wyjaśnia, jak to zrobić? – jmlopez

Powiązane problemy