2012-08-08 11 views
9

dynamicprops का एक उपवर्ग लेखन एक वस्तु को गतिशील गुण जोड़ने के लिए मुझे अनुमति देता है:क्या मक्लाब कक्षाओं (ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग) में फ्लाई पर विधियों को जोड़ना संभव है?

addprop(obj, 'new_prop') 

इस महान है, लेकिन मैं यह भी मक्खी पर इन गुणों के लिए set/get कार्यों बनाने के लिए प्यार होता। या विश्लेषण कार्य जो इन गतिशील गुणों पर काम करते हैं।

मैटलैब के साथ मेरा अनुभव अब तक रहा है, कि एक बार जब मैं कक्षा का उदाहरण बना देता हूं, तो नई विधियां जोड़ना संभव नहीं होता है। यह बहुत बोझिल है, क्योंकि मेरे ऑब्जेक्ट में बहुत अधिक डेटा हो सकता है, जिसे मुझे हर बार फिर से लोड करना होगा कि मैं एक नई विधि जोड़ना चाहता हूं (क्योंकि मुझे clear classes करना है)।

तो क्या फ्लाई पर विधियों को जोड़ने का कोई तरीका है?

+0

जब तक आप कक्षाओं को बाद में स्पष्ट करते हैं, तब तक आप नई विधियां जोड़ सकते हैं, लेकिन आप इसके आसपास जाना चाहते हैं। मुझे नहीं लगता कि सामान्य रूप से काम करेगा। –

उत्तर

10

आप गतिशील गुण जोड़ने जैसे तरीकों को जोड़ नहीं सकते हैं। हालांकि, विकास के दौरान नई विधियों को लागू करने के दो तरीके हैं जिनके लिए आपको हर बार डेटा को फिर से लोड करने की आवश्यकता नहीं होगी।

(1) मैं मानक कार्यों को अलग-अलग कार्यों के रूप में लिखता हूं, और उन्हें विकास के दौरान myMethod(obj) के रूप में कॉल करता हूं। एक बार मुझे यकीन है कि वे स्थिर हैं, मैं कक्षा हस्ताक्षर फ़ाइल में अपना हस्ताक्षर जोड़ता हूं - इसके लिए clear classes की आवश्यकता होती है, लेकिन यह बहुत देर हो चुकी है, और समय-समय पर आपको मैटलैब को बंद करना पड़ सकता है, वैसे भी ।

(2) सेट/प्राप्त विधियों के साथ, चीज़ें थोड़ा सा ट्रिकियर हैं। यदि आप नई गुण जोड़ने के लिए dynamicprops का उपयोग कर रहे हैं, तो आप उनके सेट/प्राप्त विधियों को भी निर्दिष्ट कर सकते हैं, हालांकि (संभवतः, ये विधियां/फ़ंक्शंस संपत्ति का नाम प्राप्त करना चाहेंगे ताकि वे जान सकें कि क्या संदर्भित किया जाए):

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

संपादित

(2,1) यहाँ कैसे की दुकान और परिणाम लाने के लिए एक छिपा संपत्ति (jmlopez' answer के आधार पर) स्थापित करने के लिए का एक उदाहरण है। जाहिर है इस एक बहुत सुधार किया जा सकता है अगर आप एक बेहतर विचार क्या आप वास्तव में

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

इसलिए 'myMethod' वास्तव में एक सामान्य कार्य (और क्लास विधि नहीं) होगा जिसे आप पसंद करते हैं, ठीक है? – memyself

+1

@memyself: बिल्कुल। इसके बाद, आप या तो 'myMethod' को classdef फ़ाइल में कॉपी कर सकते हैं, या बस classdef फ़ाइल में हस्ताक्षर जोड़ सकते हैं और' myMethod' को क्लास फ़ोल्डर में ले जा सकते हैं। – Jonas

+0

यह एक साफ चाल है - मैंने कभी इसके बारे में सोचा नहीं है! – memyself

3

डिज़ाइन कर रहे हैं क्योंकि मुझे लगता है कि यह सहज नहीं है मैं इस सवाल का जवाब जोड़ रहा है। कम से कम इस पल में खुद को नहीं। इस सवाल को खोजने के बाद मैंने सोचा कि मेरे पास मेरी गतिशील कक्षा के लिए सेट/प्राप्त विधियों को परिभाषित करने में सक्षम होने के लिए आवश्यक था। मैं इसे प्राप्त करना चाहता था, यह कुछ ऐसा था जो पाइथन __setattr__ विधि के साथ करता है। किसी भी मामले में, थोड़ी देर पहले @jonas द्वारा बनाई गई कक्षा के continuation हमारे कस्टम सेट विधि को जोड़ने के लिए कुछ संशोधनों के साथ है।

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 

इस कक्षा के साथ मैं सेट विधि को परिभाषित कर रहा हूं ताकि विशेषता को पारित पैरामीटर सही प्रकार पर कॉपी किया जा सके। देखने के लिए मैं निम्नलिखित उपयोग पर विचार क्या मतलब है:

>> 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 
इस के साथ

हम x विशेषता मजबूर कर दिया है 8 बिट के एक पूर्णांक है जो केवल -128 से 127 पूर्णांक पकड़ कर सकते हैं होने के लिए यह भी ध्यान दें कि प्रत्येक के वर्ग विशेषता हमें इच्छित प्रकार देता है।

+1

यह सही है। ध्यान दें कि कस्टम सेट/विधियों को परिभाषित करते समय, आप अनंत रिकर्सन के जोखिम में भाग ले सकते हैं, क्योंकि मैटलैब पार्सर हमेशा सेट विधि को कॉल करने से बचने के लिए नहीं जानता क्योंकि आप संपत्ति के मूल्य को आवंटित करते हैं। अपने जीवन को आसान बनाने के लिए (डीबगिंग उद्देश्यों के लिए भी), मूल्यों को संग्रहीत करने के लिए एक छिपी हुई संपत्ति के लिए सहायक हो सकता है, जिसे तब गेटर/सेटर विधियों द्वारा एक्सेस किया जाता है। – Jonas

+1

@ जोनास महान टिप्पणी - क्या आप छिपी संपत्ति पर थोड़ा और विस्तारित कर सकते हैं? – memyself

+0

@ जोनास, पाइथन '__dict__' चर के समान। वे अनंत रिकर्सन की संभावना का उल्लेख करते हैं [यहां] (http://docs.python.org/2/reference/datamodel.html#object.__setattr__)। क्या मैटलैब के बारे में कुछ दस्तावेज है जो बताता है कि यह कैसे करें? – jmlopez

संबंधित मुद्दे