Python类和__iter__

时间:2017-09-25 17:13:46

标签: python class iteration

在Python类中使用__iter__函数有什么好处?

在下面的代码中,我只是设置了两个简单的类。第一个类将列表作为参数,我可以在不使用__iter__函数的情况下遍历此列表。第二位代码使用__iter__函数循环遍历列表。

当已经有在类中循环的方法时使用__iter__有什么好处?

EG 1: no __iter__


class test_class:
    def __init__(self, list):
        self.container_list = list

    def print (self):
        a = self.container_list
        return a

test_list = test_class([1,2,3,4,5,6,7])

x = test_class.print(test_list)

for i in x:
    print (i)



EG 2: yes __iter__

class list_using_iter:
    def __init__(self):
        self.list = [1,2,3,4]
        self.index = -1

    def __iter__(self):
        return self

    def __next__(self):
        self.index += 1
        if self.index == len(self.list):
            raise StopIteration
        return self.list [self.index]

r = list_using_iter()
itr = iter(r)

print(next(itr))
print(next(itr))
print(next(itr))
print(next(itr))

print(next(itr)) # Raises the exception!

2 个答案:

答案 0 :(得分:1)

您的第一个示例不可迭代,但包含一个属性。您的第二个示例是可迭代的,但您只需按""另一个可迭代的。这是一个可以自行完成更多工作的迭代的例子:

import itertools

class Fibs:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __iter__(self):
        a = self.a
        b = self.b
        while True:
            yield a
            a, b = b, a + b

real_fibs = Fibs(0,1)

for i in itertools.islice(real_fibs, 10):
    print(i)

Fibs.__iter__并非简单地反驳从某些其他价值__iter__方法获得的值;它正在计算并根据需要产生新的价值。

实际上,前面是一个知道如何创建自己的迭代器的类的示例,而不是让每个对象都是可迭代的。这是一个定义next本身的版本。

class Fibs:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __iter__(self):
        return self

    def __next__(self):
        rv = self.a
        self.a, self.b = self.b, self.a + self.b
        return rv

答案 1 :(得分:0)

在这两种情况下,循环都因__iter__而起作用。在第一个示例中,print函数返回一个循环。 for关键字的实现将调用__iter__(或C实现中的相应插槽,因为所涉及的代码在C解释器中),以便遍历列表。

在你的第二个例子中,你可以写

for elt in r:
    print(elt)

会在内部调用__iter__来实现for循环。

通常,您倾向于直接使用for而不是iternext。直接使用iternext的情况是,当您生成一个将产生迭代器的回调函数时,或者当您根据另一个函数定义一个迭代器时。

就何时应该编写自己的__iter__或返回一些自己进行迭代的对象来说,这取决于你想要的功能。例如,您的第一个类更强大,因为两个人可以同时迭代列表。在第二个类中,因为您将索引存储在类本身中,所以一次只能有一个人成功使用迭代器。 但是,如果您有足够复杂的行为,那么定义自己的__iter__的第二种方法可能有意义。