Исходный контекст этой ошибки - слишком сложный фрагмент для публикации в таком вопросе. Я должен был уничтожить этот код до минимального фрагмента, который все еще показывает ошибку. Вот почему приведенный ниже код выглядит несколько странно.
В приведенном ниже коде класс 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]
?