Python中的readline()错误
我在使用readline()这个方法时遇到了问题,有时候它会返回两行而不是一行,我不知道为什么。有人能帮我吗?
这是我用记事本打开的文本文件的一部分:
at+gpsinit=2
OK
+GPSEVINIT: 1
at+gpsnmea=3
OK
at+gpsstart=0
OK
用Notepad++打开的效果:
at+gpsinit=2CR
CR LF
OKCR LF
CR LF
+GPSEVINIT: 1CR LF
at+gpsnmea=3CR
CR LF
OKCR LF
at+gpsstart=0CR
CR LF
OKCR LF
这是我在Python命令行中看到的结果:
16 : at+gpsinit=2
17 :
18 : OK
19 :
20 : +GPSEVINIT: 1
21 : at+gpsnmea=3
这是我的代码:
# Open a file
file = open("testtxt.txt", 'r')
line = 0
for current_line in file:
line += 1
print(str(line)+" : "+current_line)
# Close opend file
file.close()
3 个回答
在readline()
这个功能里肯定没有bug,因为很多人都在用它,而且用得很频繁。除非你用的是一种非常奇怪的、不是标准Python的版本,否则你用的应该也是个不错的版本。
你提供的信息还不足以让人确定你遇到问题的原因,不过我可以给你一些分析的方法,帮助你找出问题所在。
你应该仔细看看你的每一行里面有什么,特别是哪些字节是用来结束这一行的(比如'\n'
或者'\r\n'
等等),尤其要关注一下这一行at+gpsinit=2
及其结尾部分。
如果你在Unix系统上,可以用od
(或者xxd
)来查看。使用-c
选项可以打印出字符。再加上-t x1 -t c
选项,就能同时看到每个字节的十六进制输出和字符输出。
你遇到的问题很可能是因为行结束符的问题。
- Windows/Dos 通常使用
CRLF
(也就是\r\n
,在字节中是0d0a
)。 - Unix 通常使用
LF
(也就是\n
,在字节中是0a
)。 - MacOS 通常使用
CR
(也就是\r
,在字节中是0d
)。
下面是一些使用 ASCII 编码文件的例子:
$ hexdump -C test_dos.txt
00000000 68 65 6c 6c 6f 0d 0a 77 6f 72 6c 64 0d 0a |hello..world..|
0000000e
$ hexdump -C test_nix.txt
00000000 68 65 6c 6c 6f 0a 77 6f 72 6c 64 0a |hello.world.|
0000000c
$ hexdump -C test_mac.txt
00000000 68 65 6c 6c 6f 0d 77 6f 72 6c 64 0d |hello.world.|
0000000c
正如你所看到的,单词 hello
(68 65 6c 6c 6f
)后面跟着不同的字节 0d 0a
、0a
或 0d
。当你在 MS-记事本中编辑文件时,你很可能会插入 CRLF
。而 LF
在软件开发中是最常见的,所以 Notepad++ 很可能会添加这些。
现在,关于你的代码:根据上面提到的三个文件,与你的代码类似的代码会产生以下结果:
代码:
files = ('test_dos.txt', 'test_nix.txt', 'test_mac.txt')
for fname in files:
print("Reading {}".format(fname))
with open(fname) as fptr:
for line in fptr:
print("--> {!r}".format(line))
print(80*"-")
输出:
Reading test_dos.txt
--> 'hello\r\n'
--> 'world\r\n'
--------------------------------------------------------------------------------
Reading test_nix.txt
--> 'hello\n'
--> 'world\n'
--------------------------------------------------------------------------------
Reading test_mac.txt
--> 'hello\rworld\r'
--------------------------------------------------------------------------------
你可以清楚地看到,Python 在 \n
字符上进行分割,但并不会把它从输出中去掉。这就是为什么 "mac" 的例子只有一行的原因。
如果你需要处理来自不同来源的文件,可以考虑在 open
函数中使用 U
标志来激活 "通用换行符" 支持。详细信息可以查看 open 的文档。
这里有一个例子。请注意,唯一改变的是 open
的 U
参数:
files = ('test_dos.txt', 'test_nix.txt', 'test_mac.txt')
for fname in files:
print("Reading {}".format(fname))
with open(fname, 'U') as fptr:
for line in fptr:
print("--> {!r}".format(line))
print(80*"-")
输出:
Reading test_dos.txt
--> 'hello\n'
--> 'world\n'
--------------------------------------------------------------------------------
Reading test_nix.txt
--> 'hello\n'
--> 'world\n'
--------------------------------------------------------------------------------
Reading test_mac.txt
--> 'hello\n'
--> 'world\n'
--------------------------------------------------------------------------------
正如你所看到的,并不是所有文件的行为都是一样的。这可能会让你在读取文本文件时到处加上 U
。不过,我相信这不是默认设置是有原因的! :)
好的,我解决了我的问题,看来是Np给了我错误的文本文件。无论如何,我使用了这个命令:
file = open("testtxt.txt", 'r', newline="\r\n")
结果得到了正确的内容。