2011-04-07 18 views
6

Python'un listesinden yöntemleri devralan bir sınıf oluşturmaya çalışıyorum, ancak bazı ek şeyler de yapıyorum ... kod göstermek için muhtemelen daha kolay Bu noktada ...Python'ın listesinin bir alt sınıfı olarak list.insert() yöntemini öykünme

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 

Benim sorun budur ... Ben append() üzerinde yaptığı gibi insert() üzerinde nesne kabul testlerinin aynı tür gerçekleştirmek istiyorsanız, ben kodlamak için bir yol bulamıyorum Bir liste genişletme yöntemine (örneğin, list.append(), list.insert() veya list.extend()) destek vermeden yeni yöntemler. Hepsini desteklemeye çalışırsam, özyinelemeli döngüler alırım. Bu problemin en iyi yolu nedir?

DÜZENLEME: ... yerine Python'un listesinde()

çıkan kodu ... diye burada gönderme, birilerinin yardımcı ait collections.MutableSequence sınıflara hakkında öneri aldı

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

'öz = []' düşündüğün şeyi yapmaz. –

+1

'süper (HostList, self) .__ init __ (self)' hile yapardı. Kodunuzun yaptığı şey (argüman) değişkeni 'self'' [] 'a yeniden atar. –

+0

'__getitem__', bir dilim belirtilirse liste nesnesini döndürür. Başlatıcıyı, sağlanmışsa bir liste kullanacak olan __init __ (self, l = None) 'olarak değiştirebilirsiniz. Daha sonra '__getitem__' içinde, ii bir dilim nesnesi ise, o zaman' HostList (self._list [ii]) 'döndürün –

cevap

7

Bundan kaçınmanız mümkün olursa, yerleşik sınıflardan miras almayın. (Sen can, ama bu gerçekten zorlayıcı bir sebep olmaksızın size gerektiği anlamına gelmez)

Bu sınıflar hız için optimize ve bu geçersiz kılmak zorunda sonunda beri oldukça sıkıcı doğru onlardan devralan yapar edilir neredeyse her şey.

collections.MutableSequence'dan devralmak, yalnızca birkaç temel yöntemi uygulamanıza ve list'dan devralma ile gelen tüm tuhaflıklar ve uyarılar olmadan, dizi API'sinin sağlam ve tam özellikli bir uygulamasına sahip olmanıza olanak tanır.

+0

Harika puan +1 ... Bazı mücadelelerden sonra 'collections.MutableSequence' ile çalıştım ... Teşekkürler! –

6

Nesnelerinizi Host örneklerine sahip olup olmadığını kontrol etmek için kullanın ve (örn. super(HostList, self).insert(...)) işlevini kullanın ve list numaralı telefonu kullanın ve yeniden adlandırın. Sen super() ile, sizin yönteminden list 'ın yöntemi diyebiliriz

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

Daha da iyisi, eğer bir host ise 'x' döndüren statik bir yöntemi' as_host (x) 'olarak tanımlayın, ancak uygun istisnayı atar. Sonra 'süper' çağrıları tek linerler haline gelir. –

0

:

Sen gibi bir şey ile bitirmek gerekir. Bu şekilde, diğer yöntemlerle kana çekmeniz gerekmez.

3

HostList konteynerinizin değiştirilebilen konteyner arabirimini tamamen desteklemesi için zorunlu bir neden yoksa, is-a yerine has-a modelini kullanmanızı öneririm. Dilimleme (bir liste yerine bir HostList kabı döndürme) gibi işlemlerle tip tutarlılığı sağlamanın ekstra yüküne sahip olacaksınız.