我正在尝试定义默认样式列表对象:
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。
所以最后我的可怕解决方案出来了。原始和蛮力..有任何有效或简单的解决方案吗?提前谢谢。
答案 0 :(得分:6)
使用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)
答案 1 :(得分: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
答案 2 :(得分:0)
Martijn 的答案可供使用且没有错误:
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(self, 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).__setitem__(n, val)