【发布时间】:2018-05-17 22:39:15
【问题描述】:
我昨天偶然发现了一个question,它涉及枚举一个可迭代类型并产生递减索引以及可迭代项中的升序项。
在:
letters = ['a', 'b', 'c']
for i, letter in revenumerate(letters):
print('{}, {}'.format(i, letter))
输出:
2, a
1, b
0, c
我决定尝试创建一个enumerate 的子类来重新定义__iter__ 和__next__ 方法,而不是应用内置reverse 两次或简单地编写i = len(letters) - i - 1 来编写快速可靠的答案。
我原来的工作解决方案的代码如下:
class revenumerate(enumerate):
def __init__(self, iterable, start=0):
self._len = len(iterable)
self._start = start
if isinstance(iterable, dict):
self._data = iterable.keys()
else:
self._data = iterable
def __iter__(self):
_i = self._len
for _item in self._data:
_i -= 1
_ind = _i + self._start
yield _ind, _item
def __next__(self):
_i, _item = super().__next__()
_ind = self._len + 2 * self._start - _i - 1
return _ind, _item
然而,我现在意识到这段代码有冗余,因为enumerate.__iter__ 似乎产生了__next__ 的结果,这是有道理的。删除重新定义的__iter__ 后,我意识到self._data 没有在任何地方使用,所以我从__init__ 中删除了最后四行,留下以下代码,它仍然提供所需的行为。
class revenumerate(enumerate):
def __init__(self, iterable, start=0):
self._len = len(iterable)
self._start = start
def __next__(self):
_i, _item = super().__next__()
_ind = self._len + 2 * self._start - _i - 1
return _ind, _item
现在看来,传递给revenumerate 的可迭代参数除了确定整数self._len 之外没有其他用途。
我的问题是 - iterable 存储在哪里,super().__next__ 如何访问它?
使用 PyCharm 调试器快速查看 builtins.py 并没有提供很多帮助来解决这个问题(或者在我看来,在这个阶段),而且我没有很好地遍历 Python 源代码存储库。我的猜测与父类enumerate 的__new__ 或__init__ 方法有关,或者它的父类object。
【问题讨论】:
标签: python python-3.x inheritance iterator