簡體   English   中英

Python中open和codecs.open的區別

[英]Difference between open and codecs.open in Python

在 Python 中有兩種打開文本文件的方法:

f = open(filename)

import codecs
f = codecs.open(filename, encoding="utf-8")

codecs.open什么時候比open codecs.open可取?

從 Python 2.6 開始,一個好的做法是使用io.open() ,它也接受一個encoding參數,就像現在已經過時的codecs.open() 在 Python 3 中, io.openopen()內置函數的別名。 所以io.open()可以在 Python 2.6 和所有更高版本中使用,包括 Python 3.4。 見文檔: http : //docs.python.org/3.4/library/io.html

現在,對於原始問題:在 Python 2 中讀取文本(包括“純文本”、HTML、XML 和 JSON)時,您應該始終使用帶有顯式編碼的io.open()帶有顯式編碼的open()在 Python 中3. 這樣做意味着您可以正確解碼 Unicode,或者立即得到錯誤,從而更容易調試。

純 ASCII“純文本”是遙遠過去的神話。 正確的英文文本使用卷曲引號、破折號、項目符號、€(歐元符號)甚至分音符 (¨)。 不要天真! (我們不要忘記 Facade 設計模式!)

因為純 ASCII 不是一個真正的選擇,所以沒有顯式編碼的open()只能用於讀取二進制文件。

就個人而言,我總是使用codecs.open除非有明確的確定需要使用open **。 原因是有很多次我被 utf-8 輸入潛入我的程序所困擾。 “哦,我只知道它永遠是 ascii”往往是一個經常被打破的假設。

根據我的經驗,假設 'utf-8' 作為默認編碼往往是一個更安全的默認選擇,因為 ASCII 可以被視為 UTF-8,但反之則不然。 在這些情況下,當我真正知道輸入是 ASCII 時,我仍然會使用codecs.open因為我堅信“顯式優於隱式”

** - 在 Python 2.x 中,正如 Python 3 open對問題的評論所述,替換了codecs.open

在 Python 2 中有 unicode 字符串和字節串。 如果你只使用字節串,你可以讀/寫一個用open()的文件就好了。 畢竟,字符串只是字節。

例如,當您有一個 unicode 字符串並且您執行以下操作時,問題就出現了:

>>> example = u'Μου αρέσει Ελληνικά'
>>> open('sample.txt', 'w').write(example)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

因此,很明顯,您要么在 utf-8 中明確編碼您的 unicode 字符串,要么使用codecs.open為您透明地進行編碼。

如果您只使用字節串,那么沒問題:

>>> example = 'Μου αρέσει Ελληνικά'
>>> open('sample.txt', 'w').write(example)
>>>

它比這更復雜,因為當您使用+運算符連接 unicode 和 bytestring 字符串時,您會得到一個 unicode 字符串。 容易被那個咬。

此外codecs.open不喜歡傳入非 ASCII 字符的字節codecs.open

codecs.open('test', 'w', encoding='utf-8').write('Μου αρέσει')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/codecs.py", line 691, in write
    return self.writer.write(data)
  File "/usr/lib/python2.7/codecs.py", line 351, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)

關於輸入/輸出字符串的建議通常是“盡可能早地轉換為 unicode,並盡可能晚地轉換回字節串”。 使用codecs.open可以讓您非常輕松地完成后者。

請注意,您提供的是 unicode 字符串,而不是可能具有非 ASCII 字符的字節串。

當您需要打開具有特定編碼的文件時,您將使用codecs模塊。

我想codecs.open只是Python 2天的殘余,當時內置 open 具有更簡單的界面和更少的功能。 在 Python 2 中,內置open不接受編碼參數,因此如果您想使用二進制模式或默認編碼以外的其他內容,則應該使用 codecs.open 。

Python 2.6 , io 模塊幫助使事情變得更簡單。 根據官方文檔

New in version 2.6.

The io module provides the Python interfaces to stream handling.
Under Python 2.x, this is proposed as an alternative to the
built-in file object, but in Python 3.x it is the default
interface to access files and streams.

話雖如此,我能想到的codecs.open在當前場景中的唯一用途是向后兼容。 在所有其他情況下(除非您使用 Python < 2.6),最好使用io.open 同樣在Python 3.x io.openbuilt-in open相同

筆記:

codecs.openio.open之間也存在語法差異。

codecs.open :

open(filename, mode='rb', encoding=None, errors='strict', buffering=1)

io.open :

open(file, mode='r', buffering=-1, encoding=None,
     errors=None, newline=None, closefd=True, opener=None)
  • 當您要加載二進制文件時,請使用f = io.open(filename, 'b')

  • 要打開文本文件,請始終使用帶有顯式編碼的f = io.open(filename, encoding='utf-8')

然而,在python 3openio.open做同樣的事情,可以代替使用。

注意: codecs.open計划在python 2.6 中引入后被棄用並由io.open取代。 如果代碼需要與早期的 Python 版本兼容,我只會使用它。 有關 Python 中編解碼器和 unicode 的更多信息,請參閱Unicode HOWTO

當您處理文本文件並希望透明編碼和解碼為 Unicode 對象時。

暫無
暫無

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

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