3

デフォルトのスタイル リスト オブジェクトを定義しようとしています。

class ilist(list):
    def __init__(self,r=list(),dft=None):
        list.__init__(self,r)
        self.dft=dft
    def __getitem__(self,n):
        if len(self)<=n:
            for i in range(n-len(self)+1):
                self.append(self.dft)
        for i,v in enumerate(self):
            if i+1==len(self):
                return v

x=ilist()
print x[4]
print x

できます。

>>> 
None
[None, None, None, None, None]  

しかし、私の ilist を照会するのはひどいと思います。私は次の方法を試しました:

def __getitem__(self,n):
    from operator import getitem
    if len(self)<=n:
        for i in range(n-len(self)+1):
            self.append(self.dft)
    return getitem(self,n)

しかし、事実はそれが完全にself[n]に等しく、原因を示していますRuntimeError: maximum recursion depth exceeded

親クラスのlistメソッドも流用してみましたが、形はx.__getitem__(y). それをilistに適応させる方法がわかりません。

それで、ついに私のひどい解決策が出てきました。生で力ずく..効率的または簡単な解決策はありますか? 前もって感謝します。

4

3 に答える 3

7

super()オリジナルにアクセスするために使用し__getitem__ます。

def __getitem__(self,n):
    while len(self) <= n:
        self.append(self.dft)
    return super(ilist, self).__getitem__(n)

デモ:

>>> class ilist(list):
...     def __init__(self,r=list(),dft=None):
...         list.__init__(self,r)
...         self.dft=dft
...     def __getitem__(self, n):
...         while len(self) <= n:
...             self.append(self.dft)
...         return super(ilist, self).__getitem__(n)
... 
>>> il = ilist()
>>> il[3]
>>> il
[None, None, None, None]
>>> il[2] = 5
>>> il
[None, None, 5, None]
>>> il[2]
5

おそらくスライスもサポートしたいでしょう:

def __getitem__(self, n):
    maxindex = n
    if isinstance(maxindex, slice):
        maxindex = maxindex.indices(len(self))[1]
    while len(self) <= maxindex:
        self.append(self.dft)
    return super(ilist, self).__getitem__(n)

また、任意のインデックスへの割り当てもサポートする場合は、__setitem__メソッドを追加します。

def __setitem__(self, n, val):
    maxindex = n
    if isinstance(maxindex, slice):
        maxindex = maxindex.indices(len(self))[1]
    while len(self) <= maxindex:
        self.append(self.dft)
    return super(ilist, self).__setitem__(n, val)

しかし、デフォルト値の作成をヘルパー メソッドに移すことができます。

class ilist(list):
    def __init__(self, r=None, dft=None):
        if r is None:
            r = []
        list.__init__(self, r)
        self.dft=dft

    def _ensure_length(n):
        maxindex = n
        if isinstance(maxindex, slice):
            maxindex = maxindex.indices(len(self))[1]
        while len(self) <= maxindex:
            self.append(self.dft)

    def __getitem__(self, n):
        self._ensure_length(n)
        return super(ilist, self).__getitem__(n)

    def __setitem__(self, n, val):
        self._ensure_length(n)
        return super(ilist, self).__getitem__(n)
于 2013-10-30T14:51:51.923 に答える
1

必要な数の要素を追加した後、__getitem__次のように元の (オーバーライドされた) メソッドを呼び出すだけです。

class ilist(list):
    def __init__(self,r=list(),dft=None):
        list.__init__(self,r)
        self.dft=dft
    def __getitem__(self,n):
        if len(self)<=n:
            for i in range(n-len(self)+1):
                self.append(self.dft)
        return super(ilist, self).__getitem__(n)

x=ilist()
print x[4]
print x
于 2013-10-30T14:53:20.623 に答える