如何在Python中输出文件中的每一行

15
     if data.find('!masters') != -1:
         f = open('masters.txt')
         lines = f.readline()
         for line in lines:
               print lines
               sck.send('PRIVMSG ' + chan + " " + str(lines) + '\r\n')
               f.close()

我有一个名为masters.txt的文件,里面有一列昵称,我该如何一次性打印出所有行的内容?目前我的代码只能打印第一个昵称。非常感谢您的帮助。


1
f.close() 应该放在 for 循环外面吗?另外,只需要 for line in open('masters.txt'): 就可以了。 - li.davidm
1
嗯,那不行,它会打印出第一行大约5次。 - SourD
1
这是因为你的代码只读取了一行 -- 只调用了一次 readline()lines 只包含一行(顺便提一下,它末尾有一个换行符)。另一个问题是,在第一次在 linesprintsck.send() 那个单独的行之后,你关闭了文件,所以如果你尝试读取更多内容,就无法从中读取。然而,for 循环将尝试对该行中的每个 字符 进行执行,重复 printsck.send() 相同的行,直到发生错误或停止。 - martineau
5个回答

30

首先,如@l33tnerd所说,f.close应该在循环外部。

其次,你只调用了一次readline函数,在循环之前。那样只会读取第一行。Python中的文件是迭代器,所以你可以迭代文件而无需在其上调用任何方法,这将使你每次迭代获取一行:

 if data.find('!masters') != -1:
     f = open('masters.txt')
     for line in f:
           print line,
           sck.send('PRIVMSG ' + chan + " " + line)
     f.close()

最后,你在循环中引用了变量 lines;我猜你想引用的是 line

编辑:哦,还需要缩进 if 语句的内容。


2
此外,print line 应该在末尾加上逗号以避免双倍间距。 - mgiuca
3
出于同样的原因,sck.send() 可能不需要在末尾加上 '\r\n' - martineau
1
哦,对了。我甚至忘记看一下sck.send在做什么。它也不需要str。所以它应该只是sck.send('PRIVMSG ' + chan + " " + line),或者更好的是sck.send("PRIVMSG %d %s" % (chan, line)) - mgiuca
1
或者, sck.send("PRIVMSG {0} {1}".format(chan, line))。无论你偏爱哪种形式,我建议你更新你的答案。 - martineau

9
您可能需要类似以下的内容:
if data.find('!masters') != -1:
     f = open('masters.txt')
     lines = f.read().splitlines()
     f.close()
     for line in lines:
         print line
         sck.send('PRIVMSG ' + chan + " " + str(line) + '\r\n')

不要在循环的每次迭代中关闭它,打印行而不是多行。此外,使用readlines获取所有行。编辑中删除了我的另一个答案-讨论中的另一个答案比我提供的更好,因此没有复制的必要。同时使用 read().splitlines() 去掉了 \n。

1
那个方案可以工作,但我的解决方案通常更好,因为它不会首先将整个文件读入内存;它将在从文件中读入每一行时处理每一行。我方案的劣势是,在完成操作前你不能关闭文件。 - mgiuca
1
@mgiuca - 发帖者从未提到文件的大小。如果文件很小,内存不会成为问题,我假设昵称列表就是如此。 - NG.
2
是的,我一般认为如果你可以轻松使用O(1)而不需要太多麻烦,最好不要使用O(N)内存。 - mgiuca
1
看起来你回答中的代码(以及原帖的代码)都没有考虑readline()readlines()两个方法都会保留它们返回的行末换行符这一事实。结果将会打印并发送很多空白行。 - martineau
3
@SB: 那个 while 循环和两次调用 f.readline 让你的代码看起来令人不安,像 Pascal 语言一样。只需使用 for line in f 即可。 - John Machin
顺便提一下,for line in f 也会保留行末的换行符。 - martineau

6
您可以尝试这样做。它不会一次性将f的所有内容读入内存(使用文件对象的迭代器),并且在代码离开with块时关闭文件。
if data.find('!masters') != -1:
    with open('masters.txt', 'r') as f:
        for line in f:
            print line
            sck.send('PRIVMSG ' + chan + " " + line + '\r\n')

如果您正在使用旧版本的Python(2.6之前),则必须安装

from __future__ import with_statement

5

循环遍历文件。

f = open("masters.txt")
lines = f.readlines()
for line in lines:
    print line

2

你试过了吗?

for line in open("masters", "r").readlines(): print line

?

readline() 

只读取“一行”,另一方面

readlines()

读取整行并给出所有行的列表。


1
更重要的是,readlines() 会将整个文件读入内存,并保留每行及其尾随换行符,因此 print line 将输出两个换行符。使用 for line in open() 的文本文件读取编码风格在循环结束后也会保持文件处于打开状态,因为没有办法再次引用它并将其关闭。 - martineau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接