我希望有一个__iter__
方法的类,它在创建实例时依赖于cache
参数。
如果使用cache=False
创建实例,则应该像生成器一样迭代实例(根据需要创建和丢弃每个项目)。如果使用cache=True
创建实例,则该对象应创建项目列表,存储它,然后让它可以重复迭代。
所以例如(这不起作用):
class Foo(object):
def __init__(self, max=5, cache=False):
if cache:
self.items = range(max)
self.__iter__ = iter(self.items)
else:
self.__iter__ = iter(range(max))
然后,如果我这样做,预期的结果是打印0--4,并且只有一次可用。
test_obj = Foo()
for i in test_obj:
print i, # 0 1 2 3 4
for i in test_obj:
print i, # empty
但如果我这样做,预期的结果是打印0--4,并根据需要多次使用。
test_obj = Foo(cache=True)
for i in test_obj:
print i, # 0 1 2 3 4
for i in test_obj:
print i, # 0 1 2 3 4
答案 0 :(得分:2)
Python不会在实例上查找__op__
方法,只能在类上查找。因此,您从__iter__
定义__init__
的想法不会奏效。但是,您可以实现__iter__
,使其行为在__init__
中设置的值上有所不同。这是一种方式:
class Foo(object):
def __init__(self, max=5, cache=False):
if cache:
self.iterable = range(max)
else:
self.iterable = iter(xrange(max))
def __iter__(self):
return iter(self.iterable)
这是有效的,因为迭代器是可迭代的"就像一个序列一样。但是,它的__iter__
方法会自行返回(所以无论你有多少次iter
,你只能迭代它的值一次。)
答案 1 :(得分:1)
以下是一种方法:如果未进行缓存,则在第一次调用self.items
时放弃__iter__
:
class Foo(object):
def __init__(self, max_=5, cached=False):
self.items = range(max_)
self._cached = cache
def __iter__(self):
out = self.items
if not self._cached:
self.items = []
return iter(out)
行动中:
>>> test_obj = Foo()
>>> for i in test_obj:
print i,
0 1 2 3 4
>>> for i in test_obj:
print i,
>>> test_obj = Foo(cached=True)
>>> for i in test_obj:
print i,
0 1 2 3 4
>>> for i in test_obj:
print i,
0 1 2 3 4