在init中定义方法

时间:2014-07-31 21:27:00

标签: python class oop object init

我希望有一个__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

2 个答案:

答案 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