我有一个非常长的文本文件,我正在尝试使用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
有什么不对吗?我是否需要更改行终止符?
答案 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