可迭代和迭代器

Iterable and iterator

with open("weather_data.csv", 'r') as data_file:
    data = csv.reader(data_file)
    for x in data:
        print(x)

我的理解是:csv.reader(data_file)是一个iterable,它调用iter(self)和return_i作为迭代器。这个_i每次调用next()进入下一次迭代。但是,我使用 print(help(csv.reader(data_file)) 并发现

 Methods defined here:
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __next__(self, /)
 |      Implement next(self).

我的问题是,这里的方法__next__(self, /)_i每次调用的方法是一模一样的吗? _i是否也携带数据?

csv.reader 对象是它自己的迭代器。这是单遍迭代的常见做法(即只能 运行 通过一次)。我们可以通过检查来确认这一点。

>>> data
<_csv.reader object at 0x7fe5d4a057b0>
>>> iter(data)
<_csv.reader object at 0x7fe5d4a057b0> # Note: Same as above
>>> id(data)
140625091516336
>>> id(iter(data))
140625091516336 # Note: Same as above
>>> data is iter(data)
True

将它与类似列表的东西进行比较,它是可迭代的但本身不是迭代器。

>>> lst = [1, 2, 3]
>>> lst
[1, 2, 3]
>>> iter(lst)
<list_iterator object at 0x7fe5d59747f0> # Note: NOT the same as before
>>> lst is iter(lst)
False

这允许我们通过多次调用 iter(lst) 来多次迭代列表,因为每次调用都会给我们一个新的迭代器。但是你的 csv.reader 对象是单遍的,所以我们只有一个迭代器。

在Python中,每个迭代器都是可迭代的,但不是每个可迭代的都是迭代器。来自 the glossary

Iterators are required to have an __iter__() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted.