簡體   English   中英

如何在Python 2.7中一次解碼一行unicode?

[英]How do I decode unicode one line at a time in Python 2.7?

從Python 2.7加載unicode文本的正確方法如下:

content = open('filename').read().decode('encoding'):
for line in content.splitlines():
    process(line)

更新 :不,不是。請參閱答案。)

但是,如果文件非常大,我可能希望一次讀取,解碼和處理一行,這樣整個文件永遠不會一次加載到內存中。 就像是:

for line in open('filename'):
    process(line.decode('encoding'))        

for循環在打開文件句柄上的迭代是一次讀取一行的生成器。

但這不起作用,因為如果文件是utf32編碼的,那么文件中的字節(十六進制)看起來像:

hello\n = 68000000(h) 65000000(e) 6c000000(l) 6c000000(l) 6f000000(o) 0a000000(\n)

並且由for循環分割成的行分割在\\n字符的0a字節上,導致(以十六進制):

lines[0] = 0x 68000000 65000000 6c000000 6c000000 6f000000 0a
lines[1] = 0x 000000

因此, \\n字符的一部分留在第1行的末尾,其余三個字節在第2行結束(后面是第2行中的任何文本。)可以理解地在這兩行中調用decode會導致UnicodeDecodeError

UnicodeDecodeError: 'utf32' codec can't decode byte 0x0a in position 24: truncated data

因此,顯然,在0a字節上拆分unicode字節流不是將其拆分為行的正確方法。 相反,我應該分裂出現完整的四字節換行符(0x0a000000)。 但是,我認為檢測這些字符的正確方法是將字節流解碼為unicode字符串並查找\\n字符 - 這個完整流的解碼正是我試圖避免的操作。

這不是一個不常見的要求。 處理它的正確方法是什么?

怎么樣嘗試一些像:

for line in codecs.open("filename", "rt", "utf32"):
    print line

我認為這應該有效。

codecs模塊應該為您進行翻譯。

嘗試使用編解碼器模塊:

for line in codecs.open(filename, encoding='utf32'):
    do_something(line)

使用codecs.open而不是builtin open:

import codecs
for line in codecs.open('filename', encoding='encoding'):
    print repr(line)

http://docs.python.org/library/codecs.html#codecs.open

當然,在完成精心設計的stackoverflow問題后,我發現了這一刻。

codecs.open本身注意到io.open是一個更好的選擇 (注意就在鏈接目標之上)。 它並沒有被棄用,只是因為它支持一些深奧的用法(字節 - >字節編解碼器)。

io.open在Python 2.6及更高版本中可用 ,並提供與Py3的內置open相同的行為,更好地優化,並且當涉及到行結束轉換之類的東西時,不會像codecs.open那樣行為不端。 使用codecs.open的唯一原因是你需要支持Python 2.5及更早版本,否則, io.open會更好。

import io

# Use with statement for guaranteed, predictable cleanup
with io.open('filename', encoding='utf-32') as f:
    for line in f:
        process(line)

順便說一句,您可以使用io.TextIOWrapper任何已打開的二進制文件類對象轉換為無縫解碼基於文本的對象,因此如果其他人以二進制模式為您提供現有的類文件對象,您仍然可以隱式地逐行解碼有:

def process_file(f):
    if 'b' in f.mode:  # Or some better test...
        f = io.TextIOWrapper(f, encoding='utf-32')
    for line in f:
        process(line)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM