2011-04-07 26 views
6

मैं एक वर्ग है कि अजगर की सूची से तरीकों विरासत का निर्माण करने की कोशिश कर रहा हूँ, लेकिन यह भी शीर्ष पर कुछ अतिरिक्त काम करता है ... यह शायद आसान बस कोड को दिखाने के लिए है इस बिंदु पर ...अजगर की सूची का एक उपवर्ग के रूप में list.insert() विधि नकल

class Host(object): 
    """Emulate a virtual host attached to a physical interface""" 
    def __init__(self): 
    # Insert class properties here... 
    pass 

class HostList(list): 
    """A container for managing lists of hosts""" 
    def __init__(self): 
     self = [] 

    def append(self, hostobj): 
     """append to the list...""" 
     if hostobj.__class__.__name__ == 'Host': 
      self.insert(len(self), hostobj) 
     else: 
      _classname = hostobj.__class__.__name__ 
      raise RuntimeError, "Cannot append a '%s' object to a HostList" % _classname 

मेरे समस्या यह है ... अगर मैं के रूप में मैं append() पर किया था insert() पर वस्तु प्रवेश परीक्षा का एक ही तरह का प्रदर्शन करना चाहते हैं, मैं कोड करने के लिए एक तरह से नहीं मिल सकता है एक सूची में विस्तार विधि के लिए समर्थन का त्याग करने के लिए बिना नए तरीकों (यानी list.append(), list.insert(), या list.extend())। अगर मैं उन सभी का समर्थन करने की कोशिश करता हूं, तो मैं रिकर्सिव लूप के साथ उड़ जाता हूं। इस समस्या के आसपास सबसे अच्छा तरीका क्या है?

संपादित करें: मैं अजगर की सूची()

जिसके परिणामस्वरूप कोड ... यहाँ मामले में पोस्टिंग, यह किसी को मदद करता है के बजाय collections.MutableSequence उपवर्गीकरण के बारे में सुझाव ले लिया ...

from collections import MutableSequence 
class HostList(MutableSequence): 
    """A container for manipulating lists of hosts""" 
    def __init__(self, data): 
     super(HostList, self).__init__() 
     if (data is not None): 
      self._list = list(data) 
     else: 
      self._list = list() 

    def __repr__(self): 
     return "<{0} {1}>".format(self.__class__.__name__, self._list) 

    def __len__(self): 
     """List length""" 
     return len(self._list) 

    def __getitem__(self, ii): 
     """Get a list item""" 
     return self._list[ii] 

    def __delitem__(self, ii): 
     """Delete an item""" 
     del self._list[ii] 

    def __setitem__(self, ii, val): 
     # optional: self._acl_check(val) 
     return self._list[ii] 
    def __str__(self): 
     return str(self._list) 
    def insert(self, ii, val): 
     # optional: self._acl_check(val) 
     self._list.insert(ii, val) 
    def append(self, val): 
     self.insert(len(self._list), val) 
+4

'स्वयं = []' आप क्या सोचते हैं यह करता है नहीं करता है। –

+1

'सुपर (होस्टलिस्ट, स्वयं) .__ init __ (स्वयं) 'चाल करेगा। आपका कोड क्या करता है (तर्क) चर 'self'' '[]' को फिर से सौंपता है। –

+0

'__getitem__' एक स्लाइस निर्दिष्ट होने पर एक सूची ऑब्जेक्ट वापस कर देगा। आप प्रारंभकर्ता को '__init __ (स्वयं, एल = कोई नहीं) 'में बदल सकते हैं जो प्रदान की गई सूची का उपयोग करेगा। फिर '__getitem__' में, अगर ii एक टुकड़ा वस्तु है, तो वापस जाने के' HostList (self._list [ii]) ' –

उत्तर

7

आप संभवतः यह से बचने कर सकते हैं, builtin वर्गों से विरासत नहीं है। (आप कर सकते हैं, लेकिन यह है कि आप एक बहुत सम्मोहक कारण के बिना चाहिए मतलब यह नहीं है)

उन वर्गों गति के लिए अनुकूलित कर रहे हैं, और कहा कि सही ढंग से काफी थकाऊ उन लोगों से विरासत में, जब से तुम अंत ओवरराइड करने के लिए हो रही बनाता है लगभग सब कुछ।

collections.MutableSequence से प्रवेश करने के बजाय आपको केवल कुछ आवश्यक विधियों को लागू करने की अनुमति मिलती है, और list से विरासत में आने वाले सभी क्विर्क और चेतावनियों के बिना अनुक्रम API का एक मजबूत पूर्ण रूप से प्रदर्शित कार्यान्वयन प्राप्त करने देता है।

+0

ग्रेट प्वाइंट +1 ... कुछ संघर्षों के बाद, मुझे यह 'संग्रह। मटेबल सिकेंस' के साथ काम कर रहा है ... धन्यवाद! –

6

उपयोग isinstance अपने वस्तुओं की जांच अगर वे Host के उदाहरण देखने के लिए, और super (super(HostList, self).insert(...) जैसे) के बजाय यह अपने आप reimplementing से list की कार्यक्षमता का उपयोग करने, उपयोग करने के लिए।

आप की तरह कुछ के साथ खत्म करना चाहिए:

def append(self, obj): 
    """append to the list...""" 
    if not isinstance(obj, Host): 
     raise RuntimeError, "Cannot append a '%s' object to a HostList" % obj.__class__.__name__ 
    super(HostList, self).append(obj) 
+1

इससे भी बेहतर, एक स्थिर विधि 'as_host (x)' को परिभाषित करें जो 'x' लौटाता है यदि यह होस्ट है, और उपयुक्त अपवाद फेंकता है। फिर 'सुपर' कॉल एक-लाइनर बन जाते हैं। –

0

आप super() के साथ, अपने विधि से list की विधि कह सकते हैं। इस तरह आपको अन्य विधियों के साथ इसे जोड़ने की आवश्यकता नहीं है।

3

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