Python认为3000行文本文件长一行?

时间:2010-02-02 14:05:35

标签: python text character-encoding newline

我有一个非常长的文本文件,我正在尝试使用Python进行处理。

但是,以下代码:

for line in open('textbase.txt', 'r'):
    print 'hello world'

仅产生以下输出:

hello world

就好像Python认为文件只有一行长,虽然它在文本编辑器中查看时长达数千行。使用 file 命令在命令行上检查它会给出:

$ file textbase.txt
textbase.txt: Big-endian UTF-16 Unicode English text, with CR line terminators

有什么不对吗?我是否需要更改行终止符?

4 个答案:

答案 0 :(得分:25)

根据documentation for open(),您应该在模式中添加U

open('textbase.txt', 'Ur')

这样可以启用“universal newlines”,可以将它们标准化为\n

但是,正确的做法是在翻译换行符之前将UTF-16BE解码为Unicode对象 first 。否则,0x0d字节可能会被错误地转换为0x0a,从而导致

  

UnicodeDecodeError:'utf16'编解码器无法解码位置12中的字节0x0a:截断数据。

Python的codecs module提供了一个open函数,可以解码Unicode并同时处理换行符:

import codecs
for line in codecs.open('textbase.txt', 'Ur', 'utf-16be'):
    ...

如果文件具有字节顺序标记(BOM)并指定'utf-16',则它会检测字节顺序并为您隐藏BOM。如果没有(因为BOM是可选的),那么该解码器将继续使用你的系统的字节序,这可能不会很好。

自己指定字节序(使用'utf-16be')不会隐藏BOM,因此您可能希望使用此hack:

import codecs
firstline = True
for line in codecs.open('textbase.txt', 'Ur', 'utf-16be'):
    if firstline:
        firstline = False
        line = line.lstrip(u'\ufeff')

另请参阅:Python Unicode HOWTO

答案 1 :(得分:6)

你可能会发现它是“带有CR线路终结器”的游戏。如果你正在使用一个使用换行符作为行终止符的平台,它将你的文件视为一个很大的行。

更改输入文件,使其使用正确的行终止符。你的编辑器可能比你的Python实现更宽容。

据我所知,CR行结尾是Mac的东西,您可以使用U模式修饰符open根据找到的第一行终结符自动检测。

答案 2 :(得分:1)

看起来你的文件只有CR终止的行,Python可能期望LF或CRLF。尝试使用'通用换行符':

for line in open('textbase.txt', 'rU'):
    print 'hello world'

http://docs.python.org/library/functions.html?highlight=open#open

答案 3 :(得分:-1)

open()返回一个文件对象。你需要使用:

for line in open('textbase.txt', 'r').readlines():
    print line