对于循环和开放语句

时间:2018-04-12 08:53:53

标签: python loops file-io iteration

我理解为什么第一个for循环有效;根据{{​​1}}方法,该循环基本上是循环遍历列表。

第二个 readlines()循环对我没有意义。循环打开文件,但由于for语句的默认值为 read ,因此每次迭代时输出不应是一个大字符串中的整个文件,而不是单个线?

以下是代码:

open

3 个答案:

答案 0 :(得分:3)

你误解了'默认'这里。您找到的默认值是关于文件模式;默认设置是打开文件进行读取。此时不会读取该文件,它告诉操作系统您要访问已经存在且可由您的进程读取的文件。

open()总是返回一个文件对象。并且文件对象是可迭代的,因此如果打开它以供阅读(因此模式为'r''w+''a+'),您可以循环遍历一个。

来自open() documentation

  

打开文件并返回相应的file object

  

mode 是一个可选字符串,用于指定打开文件的模式。它默认为'r',这意味着可以在文本模式下打开。其他常见值为'w'用于写入(如果文件已存在则截断文件),'x'用于独占创建,'a'用于追加[。]

open()总是返回一个继承自io.IOBase的对象,它会说明迭代:

  

IOBase(及其子类)支持迭代器协议,这意味着可以迭代IOBase对象,从而产生流中的行。线路的定义略有不同,具体取决于流是二进制流(产生字节)还是文本流(产生字符串)。

你应该总是在.readlines()上迭代迭代文件;后者在一步中将所有行读入内存,将所有这些行放入列表中,然后返回该列表。当您打开的文件很大时,这肯定会导致问题。如果您只需要访问单独的行,逐个访问,文件本身的迭代将只根据需要创建行,并且缓冲负责使这个效率更高(要求操作系统以方便的块提供数据以供Python处理成行。

请注意,即使,如果 open()返回包含所有文件内容的单个字符串,则迭代将在字符序列上进行;你不会看到重复的文件内容。您可以使用file.read()命令尝试此操作:

>>> with open('/tmp/demo.txt', 'w') as outputfile:  # opened for writing
...     outputfile.write(  # write 3 lines
...         'Neque porro quisquam\n'
...         'est qui dolorem ipsum\n'
...         'quia dolor sit amet\n')
...
63
>>> for i, value in enumerate(open('/tmp/demo.txt').read()):  # read everything into a string
...     if i > 5:  # limit the output, enumerate provided us with an index
...         break
...     print(value)
...
N
e
q
u
e

文件数据不会重复的另一个原因是文件与传统磁带非常相似:文件具有文件位置,当您从中读取数据时,文件位于文件中它,一旦你到达终点,这个位置就不会自动回到起点。无需重新打开文件,或使用file.seek()方法将文件位置重新设置为开始,您只能读取数据一次

>>> with open('/tmp/demo.txt') as inputfile:
...     print(len(inputfile.read()))  # get all data, and print the length
...     print(len(inputfile.read()))  # try again, note that we got no data this time!
...     __ = inputfile.seek(0)   # rewind to the start
...     print(len(inputfile.read()))  # try again, now we get data again
...
63
0
63

答案 1 :(得分:0)

循环

for i in iterable: 
    # some code with i

基本上

的简写
iterator = iter(iterable)
while True:
    try:
        i = next(iterator)            
    except StopIteration:
        break
    # some code with i

因此for循环从迭代构造的迭代器中逐一提取值,并自动识别迭代器何时耗尽并停止。

恰好,open的返回值是一个迭代器,为每次调用__next__方法提供一行

加成:

在您的情况下,open('test.txt')返回一个迭代器,因此在其上调用__iter__将返回迭代器本身。

>>> it = open('test.txt')
>>> iter(it) is it
True

答案 2 :(得分:0)

检查python文档: https://docs.python.org/3/library/functions.html#open

  

默认模式为' r' (打开阅读文本,' rt'的同义词)。对于二进制读写访问,模式' w + b'打开并将文件截断为0字节。 ' R + B'打开文件而不截断。

     

如概述中所述,Python区分二进制和文本I / O.以二进制模式打开的文件(包括模式参数中的' b')将内容作为字节对象返回,而不进行任何解码。在文本模式下(默认情况下,或者当模式参数中包含'时),文件内容将作为str返回,首先使用平台相关编码或使用如果给定,则指定编码。

由于open()功能的默认设置