min*_*ief 47 python inheritance list
我有兴趣使用python列表对象,但功能稍有改动.特别是,我希望列表是1索引而不是0索引.例如:
>> mylist = MyList()
>> mylist.extend([1,2,3,4,5])
>> print mylist[1]
Run Code Online (Sandbox Code Playgroud)
输出应为:1
但是,当我改变了__getitem__()
和__setitem__()
方法,要做到这一点,我得到一个RuntimeError: maximum recursion depth exceeded
错误.我对这些方法进行了很多修改,但这基本上就是我在那里所做的:
class MyList(list):
def __getitem__(self, key):
return self[key-1]
def __setitem__(self, key, item):
self[key-1] = item
Run Code Online (Sandbox Code Playgroud)
我想问题是它self[key-1]
本身正在调用它定义的相同方法.如果是这样,我如何使用list()
方法而不是MyList()
方法?我尝试使用super[key-1]
而不是self[key-1]
导致投诉TypeError: 'type' object is unsubscriptable
有任何想法吗?另外,如果你能指出一个很好的教程,那就太好了!
谢谢!
Gin*_*kas 53
使用该super()
函数调用基类的方法,或直接调用该方法:
class MyList(list):
def __getitem__(self, key):
return list.__getitem__(self, key-1)
Run Code Online (Sandbox Code Playgroud)
要么
class MyList(list):
def __getitem__(self, key):
return super(MyList, self).__getitem__(key-1)
Run Code Online (Sandbox Code Playgroud)
但是,这不会改变其他列表方法的行为.例如,索引保持不变,这可能导致意外结果:
numbers = MyList()
numbers.append("one")
numbers.append("two")
print numbers.index('one')
>>> 1
print numbers[numbers.index('one')]
>>> 'two'
Run Code Online (Sandbox Code Playgroud)
Bin*_*ile 28
相反,使用相同的方法将整数子类定义为将所有数字定义为您设置它们的减1.瞧.
对不起,我不得不这样做.这就像是关于微软将黑暗定义为标准的笑话.
Ale*_*vic 16
您可以通过创建一个继承自collections.MutableSequence的类来避免违反Liskov Substitution原则,该类是一个抽象类.它看起来像这样:
class MyList(collections.MutableSequence):
def __init__(self, l=[]):
if type(l) is not list:
raise ValueError()
self._inner_list = l
def __len__(self):
return len(self._inner_list)
def __delitem__(self, index):
self._inner_list.__delitem__(index - 1)
def insert(self, index, value):
self._inner_list.insert(index - 1, value)
def __setitem__(self, index, value):
self._inner_list.__setitem__(index - 1, value)
def __getitem__(self, index):
return self._inner_list.__getitem__(index - 1)
Run Code Online (Sandbox Code Playgroud)
这里有一个问题(尽管可能还有更多).如果您将新列表编入索引,如下所示:
l = MyList()
l[0]
Run Code Online (Sandbox Code Playgroud)
你会真的打电话给:
self._inner_list[-1]
Run Code Online (Sandbox Code Playgroud)
这将为您提供最后一个元素.因此,如果要为列表提供该功能,则必须对方法进行其他检查,并确保保留反向索引.
编辑:
这是新代码,我认为不应该有任何问题.
def indexing_decorator(func):
def decorated(self, index, *args):
if index == 0:
raise IndexError('Indices start from 1')
elif index > 0:
index -= 1
return func(self, index, *args)
return decorated
class MyList(collections.MutableSequence):
def __init__(self):
self._inner_list = list()
def __len__(self):
return len(self._inner_list)
@indexing_decorator
def __delitem__(self, index):
self._inner_list.__delitem__(index)
@indexing_decorator
def insert(self, index, value):
self._inner_list.insert(index, value)
@indexing_decorator
def __setitem__(self, index, value):
self._inner_list.__setitem__(index, value)
@indexing_decorator
def __getitem__(self, index):
return self._inner_list.__getitem__(index)
def append(self, value):
self.insert(len(self) + 1, value)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
40672 次 |
最近记录: |