2016-04-19 10 views
5

वर्तमान स्थिति के हिस्से के रूप

मैं एक सार आधार वर्ग, जानता है कि है, जो एक numpy सरणी के रूप में डेटा को होस्ट करता है इस डेटा काम करने के लिए कैसे, और कैसे आकर्षित करने के लिए matplotlib व्याख्या कर सकते हैं जो है यह।कॉलिंग वर्ग विधि प्रारंभ

class PlotData(): 
    """Base Class""" 
    subclasslist = [] 

    @classmethod 
    def register(cls): 
     super().subclasslist.append(cls) 

    def __new__(self, initdata, *args, **kwargs): 
     for subclass in subclasslist: 
      try: 
       subclass.__test__(initdata) 
      except AssertionError: 
       continue 
      else: 
       break 
     else: 
      raise TypeError("Initdata does not fit any known subclass") 
     return subclass(initdata, *args, **kwargs) 

class Plot3D(PlotData): 
    """Subclass for 3d-plotting data""" 
    def __test__(initdata): 
     assert Data_is_the_right_kind 

class Plot_XY(PlotData): 
    """Subclass for for plotting X-Y relations of data""" 
    def __test__(initdata): 
     assert Data_is_the_right_kind 

अंक

अब, इस मुद्दे कैसे subclasslist में श्रेणी संदर्भ प्राप्त करने के लिए है: विभिन्न प्रकार के डेटा को समायोजित करने के लिए, यह उपवर्गों की एक संख्या है, इस तरह है। सबसे पहले मैं कक्षा के शरीर में सुपर() रजिस्टर() को कॉल करना चाहता था, लेकिन मैं वर्ग के संदर्भ में असमर्थ हूं, जो मैं सूची में स्टोर करना चाहता हूं। एक छोटी सी खोज ने दो संभावित समाधान दिए हैं, और मैं सोच रहा था कि सबसे अच्छा क्या था।

समाधान 1

, हर वर्ग के परिभाषा के बाद एक फोन जोड़ना इस तरह:

class Plot_XY(PlotData): 
    """Subclass for for plotting X-Y relations of data""" 
    def __test__(initdata): 
     assert Data_is_the_right_kind 
Plot_XY.register() 

यह काम करता है, लेकिन मेरे लिए एक बहुत गंदे समाधान की तरह लगता है - वर्ग संरचना का एक बहुत ही महत्वपूर्ण हिस्सा है शरीर के बाहर स्थित है।

समाधान 2

एक और संभावना कक्षा सजावट हो सकती है। हालांकि, मैंने पहले कभी उनका उपयोग नहीं किया है, और जिन उदाहरणों को मैंने पाया है, वे आम तौर पर विधियों को ओवरराइड/जोड़ने के लिए उपयोग किए जाते हैं। (here और here, उदाहरण के लिए)। मैं समारोह सज्जाकार से परिचित हूँ हालांकि, और निम्न मोटे तौर पर स्पष्ट है कि मैं क्या कर रहा हूँ के लिए लक्ष्य (और एक नीचे dumbed संस्करण दुभाषिया में काम करता है) बनाना चाहिए:

def some_creative_decorator_name(cls): 
    cls.register() 
    return cls 

या कम से कम, कुछ है कि कार्यों समाधान 1 की तरह लेकिन ऐसा लगता है:

@some_creative_decorator_name 
class Plot_XY(PlotData): 
    """Subclass for for plotting X-Y relations of data""" 
    def __test__(initdata): 
     assert Data_is_the_right_kind 

ऐसा लगता है कि यह भी काम करता है, लेकिन क्या यह विरासत की तरह सामान को खराब कर देगा? यह लिंक किए गए पृष्ठों में दी गई चिंताओं में से एक था, और मैं वास्तव में इस पर बहुत अधिक हिम्मत नहीं करता हूं। (मैं इसे आगे उपवर्ग के लिए लोगों को उम्मीद कर रहा हूँ, लेकिन मैं नहीं है वास्तव में यह असंभव बनाने के लिए अगर यह वांछित है चाहता हूँ।)

(बेशक अन्य समाधान के रूप में अच्छी तरह से स्वागत है।)

उत्तर

6

तुम क्या कर रहे क्योंकि यह पहले से ही प्रदान की जाती है बेकार है:

>>> class A(object):pass 
... 
>>> class B(A):pass 
... 
>>> class C(A): pass 
... 
>>> A.__subclasses__() 
[<class '__main__.B'>, <class '__main__.C'>] 
>>> 

रखने के लिए कोई जरूरत नहीं है अपनी खुद की subclasslist जब अजगर पहले से ही आप के लिए एक प्रदान करता है।

ध्यान दें कि यह उपवर्गों की उपवर्गों शामिल नहीं है:,

>>> def all_subclasses(klass): 
...  for sub in klass.__subclasses__(): 
...   yield sub 
...   yield from all_subclasses(sub) 
... 
>>> list(all_subclasses(A)) 
[<class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>] 

यह कहा कि अगर आप चाहते हैं:

>>> class D(B):pass 
... 
>>> A.__subclasses__() 
[<class '__main__.B'>, <class '__main__.C'>] 

हालांकि यह काफी आसान सभी उपवर्गों को मिल रहा है इस कार्यक्षमता को दोहराना यह देखना आसान है कि डिफ़ॉल्ट विधि कैसे काम करती है।आप देख सकते हैं यह type का एक तरीका है जिसके metaclass object की है कि

>>> '__subclasses__' in dir(object) 
False 
>>> '__subclasses__' in dir(type) 
True 

तो यहाँ: और आपको लगता है कि पता चलता है चाहते हैं। इसे सही ढंग से दोहराने का तरीका है अपने कस्टम मेटाक्लास को लिखना।

मूल रूप से एक metaclass डेकोरेटर दृष्टिकोण तथापि के समान है:

  • यह अधिक सामान्य है, क्योंकि आप सामान कर सकते हैं इससे पहले कि वर्ग बनाया जाता है, को नियंत्रित कि यह कैसे बनाया जाता है और कुछ बाद में करते हैं। एक सजावटी को कक्षा वस्तु प्राप्त होने पर प्राप्त होता है और केवल पोस्ट-निर्माण सामग्री
  • वे विरासत में हैं, इसलिए आपको प्रत्येक वर्ग के लिए कुछ भी स्पष्ट नहीं करना है, बल्कि केवल बेस क्लास में भी जोड़ना है।

मैं यहाँ विस्तार में नहीं जा रहा हूँ। मेटाक्लास पर अधिक जानकारी के लिए What is a metaclass in Python? देखें।

+0

धन्यवाद! यह सहायता करता है। मैं पहले कभी '__subclasses__' के बारे में नहीं जानता था। और यह मेरा काम बहुत आसान बना रहा है। मैं मेटाक्लास के बारे में कुछ भी पढ़ूंगा, जो मेरे लिए भी नया है। – Gloweye

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