Исходный контекст этой ошибки - слишком сложный фрагмент для публикации в таком вопросе. Я должен был уничтожить этот код до минимального фрагмента, который все еще показывает ошибку. Вот почему приведенный ниже код выглядит несколько странно.
В приведенном ниже коде класс Foo может считаться запутанным способом получить что-то вроде xrange.
class Foo(object):
def __init__(self, n):
self.generator = (x for x in range(n))
def __iter__(self):
for e in self.generator:
yield e
Действительно, Foo, похоже, очень похож на xrange:
for c in Foo(3):
print c
# 0
# 1
# 2
print list(Foo(3))
# [0, 1, 2]
Теперь подкласс Bar в Foo добавляет только метод __len__:
class Bar(Foo):
def __len__(self):
return sum(1 for _ in self.generator)
Bar ведет себя точно так же, как Foo при использовании в for -loop:
for c in Bar(3):
print c
# 0
# 1
# 2
НО:
print list(Bar(3))
# []
Я предполагаю, что при оценке list(Bar(3)) метод __len__ Bar(3) получает вызов, тем самым используя генератор.
(Если это предположение верно, вызов Bar(3).__len__ не нужен, ведь list(Foo(3)) дает правильный результат, даже если Foo не имеет метода __len__.)
Эта ситуация раздражает: нет никаких веских причин для list(Foo(3)) и list(Bar(3)) для получения разных результатов.
Можно ли исправить Bar (без, конечно, избавления от своего метода __len__), так что list(Bar(3)) возвращает [0, 1, 2]?