有没有简单的方法可以覆盖列表对象的方法__getitem__? [英] Is there a simple way to override the list object's method __getitem__?

查看:81
本文介绍了有没有简单的方法可以覆盖列表对象的方法__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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆