有没有简单的方法可以覆盖列表对象的方法__getitem__? [英] Is there a simple way to override the list object's method __getitem__?
问题描述
我正在尝试定义默认的样式列表对象:
I am trying to define a default style list object:
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太糟糕了. 我尝试了以下方法:
But I think it's terrible to query my ilist. I've tried the following method:
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
but the fact shows it totally equals self[n] and causes RuntimeError: maximum recursion depth exceeded
我也尝试借用父类list
方法.但是形式是x.__getitem__(y)
.我不知道如何使它适应ilist.
I also tried to borrow the parent class list
method .But the form isx.__getitem__(y)
. I don't know how to adapt it to ilist.
所以最后我提出了可怕的解决方案.原始和蛮力.是否有任何有效或简单的解决方案?预先感谢.
So finally my terrible solution comes out. Raw and brute force..Is there any effecient or simple solution? Thanks in advance.
推荐答案
使用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
您可能还希望支持切片:
You probably want to support slicing as well:
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__
方法:
and if you wanted to support assignment to arbitrary indices as well, add a __setitem__
method:
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)
,但是您可以将默认值创建移到辅助方法中:
but then you could move the default-value creation out to a helper method:
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)
这篇关于有没有简单的方法可以覆盖列表对象的方法__getitem__?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!