【发布时间】:2020-11-02 13:36:19
【问题描述】:
这是关于“发电机”使用的正确术语的问题。我们看一下内置函数open()返回的文件对象。
1。内置open()函数,官方文档
在official python documentation 中,然后open() 函数据说返回一个“文件对象”,而documentation for file object 并没有真正说明这是什么生物,除了它有read() 和write()方法和那个
文件对象也称为类文件对象或流。
????♂️ 这很有帮助,对吧?
2。网上的话
这里有一些例子,其中open() 返回的文件对象被称为生成器。
2.1。 How to Use Generators and yield in Python (Realpython.com)
(强调我的)
open() 返回一个 generator 对象,您可以懒惰地逐行迭代
2.2. Lazy Method for Reading Big File in Python?
(接受 400+ 分的答案,强调我的)
如果文件是基于行的,则文件对象已经是一个惰性生成器 行数:
for line in open('really_big_file.dat'): process_data(line)
2.3。 Generators in Python — 5 Things to Know (medium.com)
(强调我的)
使用
open()方法打开EEG文件会创建一个文件 对象,它作为一个 generator 产生一行数据作为 每次都是字符串。
人们可能很容易从 Internet 上的任何地方找到更多此类示例。
3。测试open() 返回的文件对象是否为生成器
按照How to check if an object is a generator object in python?,我们可以对文件对象进行一些测试:
In [7]: o = open(r'C:\tmp\test.csv')
In [8]: type(o)
Out[8]: _io.TextIOWrapper
In [9]: import inspect
In [10]: inspect.isgenerator(o)
Out[10]: False
In [12]: inspect.isgeneratorfunction(o)
Out[12]: False
In [13]: import types
In [14]: isinstance(o, types.GeneratorType)
Out[14]: False
所有这些测试都失败了,暗示open() 返回的文件对象不是生成器。尽管如此,很多人还是倾向于称它为生成器。
4。包括或不包括发电机?
那么,python 爱好者们,open() 函数返回一个生成器是否正确?并执行以下操作
for line in open('file.csv'):
do_something(line)
涉及使用生成器?
【问题讨论】:
-
既然你可以
seek一个打开的文件:显然不行。 -
__next__的__next__方法的source code 表示TextIoWrapper是TextIoBase的子类,IOBase的子类。 also says 表示“IOBase 对象可以迭代 yielding 流中的行。”。他们在那里使用术语“产量”。使用for line in open(file)读取行时会说涉及到一些生成器吗? -
在该段落中,它明确使用了 iterator 这个词,而不是生成器。 “yield”这个词很可能是在英语意义上使用的,而不是在 Python 关键字意义上。
-
你也可以这样做:
l = [1, 2, 3] ; for num in l: ...这不会使列表成为生成器,它是一个可迭代。就像文件对象一样。您可以使用它像生成器一样表现,但区别如上所述,您可以seek返回文件。你不能倒带发电机 -
有道理。我检查了
TextIOWrapper的源代码,似乎除了是一个可迭代对象之外,它还是一个 iterator (它具有返回self的__iter__方法)。
标签: python