228

私は本当に混乱していcodecs.open functionます。私がする時:

file = codecs.open("temp", "w", "utf-8")
file.write(codecs.BOM_UTF8)
file.close()

それは私にエラーを与える

UnicodeDecodeError: 'ascii' コーデックは位置 0 のバイト 0xef をデコードできません: 序数が範囲外です (128)

私が行った場合:

file = open("temp", "w")
file.write(codecs.BOM_UTF8)
file.close()

それは正常に動作します。

質問は、なぜ最初の方法が失敗するのですか? そして、どのようにボムを挿入しますか?

2番目の方法が正しい方法である場合、使用するポイントは何codecs.open(filename, "w", "utf-8")ですか?

4

6 に答える 6

297

問題はcodecs.BOM_UTF8、Unicode 文字列ではなく、バイト文字列であることだと思います。ファイル ハンドラーは、「UTF-8 でエンコードされたテキストとして Unicode を記述することを意図しているのに、バイト文字列を渡してしまった!」に基づいて、あなたの本当の意味を推測しようとしていると思われます。

ファイルが UTF-8 としてエンコードされるように、バイト オーダー マークの Unicode 文字列 (つまり、Unicode U+FEFF) を直接記述してみてください。

import codecs

file = codecs.open("lol", "w", "utf-8")
file.write(u'\ufeff')
file.close()

(それは正しい答えを与えるようです - バイト EF BB BF を持つファイル。)

編集:エンコーディングとして「utf-8-sig」を使用するというS.ロットの提案は、BOMを自分で明示的に記述するよりも優れていますが、以前に何がうまくいかなかったかを説明しているため、この回答をここに残します。

于 2009-06-01T09:46:58.933 に答える
194

以下をお読みください: http://docs.python.org/library/codecs.html#module-encodings.utf_8_sig

これを行う

with codecs.open("test_output", "w", "utf-8-sig") as temp:
    temp.write("hi mom\n")
    temp.write(u"This has ♭")

結果のファイルは、予想される BOM を持つ UTF-8 です。

于 2009-06-01T09:58:14.107 に答える
19

これを使うだけでとても簡単です。ライブラリは必要ありません。

with open('text.txt', 'w', encoding='utf-8') as f:
    f.write(text)
于 2021-08-12T11:17:48.227 に答える
12

@S-Lott は適切な手順を提供しますが、Unicodeの問題を拡張すると、Pythonインタープリターはより多くの洞察を提供できます。

Jon Skeet はcodecsモジュールについて (異常に) 正しいです - それにはバイト文字列が含まれています:

>>> import codecs
>>> codecs.BOM
'\xff\xfe'
>>> codecs.BOM_UTF8
'\xef\xbb\xbf'
>>> 

別のニットを選ぶとBOM、標準のUnicode名があり、次のように入力できます。

>>> bom= u"\N{ZERO WIDTH NO-BREAK SPACE}"
>>> bom
u'\ufeff'

次の方法でもアクセスできますunicodedata

>>> import unicodedata
>>> unicodedata.lookup('ZERO WIDTH NO-BREAK SPACE')
u'\ufeff'
>>> 
于 2009-06-01T10:12:39.257 に答える
10

file * nixコマンドを使用して、utf-8ファイル内の不明な文字セットファイルを変換します

# -*- encoding: utf-8 -*-

# converting a unknown formatting file in utf-8

import codecs
import commands

file_location = "jumper.sub"
file_encoding = commands.getoutput('file -b --mime-encoding %s' % file_location)

file_stream = codecs.open(file_location, 'r', file_encoding)
file_output = codecs.open(file_location+"b", 'w', 'utf-8')

for l in file_stream:
    file_output.write(l)

file_stream.close()
file_output.close()
于 2012-02-08T20:35:11.170 に答える