2013-07-10 8 views
5

私は、UTF-8でエンコードされた文字列で構成される文字列を作成する定義があります。出力ファイルは、'w+', "utf-8"引数を使用して開きます。Python、出力をUTF-8にエンコードする

私はx.write(string)しようとするとしかし、私は通常、たとえば、あなたが `プリント(u'something ')を行うだろうためであると仮定しUnicodeEncodeError: 'ascii' codec can't encode character u'\ufeff' in position 1: ordinal not in range(128)

を取得します。しかし、私は変数と引用符を使用する必要があります '_'それを否定する...

何か提案がありますか?

編集:ここに実際のコード:

source = codecs.open("actionbreak/" + target + '.csv','r', "utf-8") 
outTarget = codecs.open("actionbreak/" + newTarget, 'w+', "utf-8") 
x = str(actionT(splitList[0], splitList[1])) 
outTarget.write(x) 

基本的にこのすべてをやっていることになっているが、私は次のようになり、文字列を大量に構築されています

[日木曜 Deliverables]= CASE WHEN things = 11 THEN C ELSE 0 END

+1

x.write(string.encode( 'utf-8'))を実行しましたか? – xgord

+0

ファイルを開くために使用している実際のコードと、どこから 'u '\ ufeff'を得ているのかを表示してください。 – geoffspear

+0

ありがとう、詳細を追加しました –

答えて

5

codecs.open()をお使いですか? Python 2.7に組み込まれているopen()は、特定のエンコーディングをサポートしていないため、ASCII以外の文字列を手動でエンコードする必要がありますが、他の文字列はcodecs.open()でサポートされています。文字列。


あなたが実際にあなたの追加されたコードで行く、codecs.open()を使用している、と自分自身を物事を見てのビットの後、私は自動的に処理するこれ、エンコーディング"utf-8-sig"で入力および/または出力ファイルを開こうと提案したようUTF-8のBOM(セクションの最後にあるhttp://docs.python.org/2/library/codecs.html#encodings-and-unicodeを参照してください)私はそれが入力ファイルの場合のみ問題になると思いますが、これらの組み合わせ(utf-8-sig/utf-8、utf-8/utf-8-sig、utf-8-sig/utf-8-sig)が動作する場合、入力ファイルがPythonのデフォルトのUTF-8コーデックのように、BOMとは異なるUnicode形式でエンコードされるBOMを通常の文字として解釈するので、入力に問題はなく出力できます。


はちょうどあなたがcodecs.open()を使用する場合、それはUnicode文字列ではなく、エンコードされた1見込んこれに気づいた、しかし...。試してくださいx = unicode(actionT(splitList[0], splitList[1]))

Unicode文字列(http://wiki.python.org/moin/UnicodeEncodeErrorを参照)をデコードしようとしたときにあなたのエラーが発生することもありますが、私はactionT()またはあなたのリスト分割は、それらが扱われますUnicode文字列に何かをしない限り、それが起こってしなければならないとは思いません非Unicode文字列として扱います。

+0

はい、私はcodecs.open()を使用しています。それでも、私はまだこのエラーに遭遇しているようです。 –

+0

@RazzleDazzleそれはBOMの問題です。私は私の答えにいくつかの追加を加え、それらを試してみて、何があっても何が起こっているのかを見ます。 – JAB

+0

BOMをスキップするエンコーディングを使用するよう提案した後、約3つの文字列が出力ファイルに正常に渡された後、このエラーが表示されるようになりました。 'UnicodeEncodeError: 'ascii' tは位置1-3の文字をエンコードします:序数は範囲内にありません(128)。 –

1

xgordがありますしかし、それ以上の啓蒙のためには、それは正確に何を意味するの価値がある\ufeffを意味します。 BOMまたはbyte order markとして知られています。基本的には、ユニコードの初期段階のコールバックで、人々がユニコードをどのようにしたいかに同意できない場合があります。これで、すべてのUnicodeの文書は、彼らは彼らのバイトを手配することを決定した順序によって\ufeff\uffefのいずれかで始まるされている。

あなたは問題があなたのことであることを確認することができます最初の場所でそれらの文字に誤りがヒットした場合utf-8として解読しようとしていないので、ファイルはおそらくまだ素晴らしいです。

+0

あなたはやや間違っていますが、BOMは常に\\feffです。 BOMの実際のエンコーディングは異なりますが、コードポイントは常にU + FEFFです。あなたが '\ uffef'としてそれを読んでいるなら、あなたはエンディアンを反転させます。 – JAB

+0

@JAB微妙な点なら良い。 –

+0

(もちろん 'b '\ xef \ xbb \ xbf''の場合、エンコーディングはUTF-8です) – JAB

5

python 2.xには、バイト文字列とユニコード文字列という2種類の文字列があります。最初のものはバイトと最後の1 - ユニコードコードポイントを含みます。それは決定するのは簡単です、それは文字列の種類 - unicode文字列はuで始まる:ASCIIの範囲にあるため

# byte string 
>>> 'abc' 
'abc' 

# unicode string: 
>>> u'abc абв' 
u'abc \u0430\u0431\u0432' 

「ABC」文字は、同じです。 \u0430はUnicodeコードポイントであり、ASCII範囲外です。 "コードポイント"は、Pythonのユニコードポイントの内部表現であり、ファイルに保存することはできません。 には、を最初にバイトにエンコードする必要があります。ここではどのようにエンコードされたUnicode文字列は、(それがエンコードされているとして、それはバイト文字列になります)のようになります。

>>> s = u'abc абв' 
>>> s.encode('utf8') 
'abc \xd0\xb0\xd0\xb1\xd0\xb2' 

このエンコードされた文字列は、現在ファイルに書き込むことができます。今すぐ

>>> s = u'abc абв' 
>>> with open('text.txt', 'w+') as f: 
...  f.write(s.encode('utf8')) 

、それがために重要ですファイルに書き込むときに使用したエンコーディングを覚えておいてください。データを読み取れるようにするためには、コンテンツをデコードする必要があります。ここではどのようなデータを復号化することなく次のようになります。あなたが見

>>> with open('text.txt', 'r') as f: 
...  content = f.read() 
>>> content 
'abc \xd0\xb0\xd0\xb1\xd0\xb2' 

は、我々はs.encode(「UTF8」)と全く同じ符号化されたバイトを、持っています。コーディングの名前を提供するために必要とされるデコードするには、次のデコード後

>>> content.decode('utf8') 
u'abc \u0430\u0431\u0432' 

を、私たちは、Unicodeのコードポイントを持つ当社のUnicode文字列をバック持っています。

>>> print content.decode('utf8') 
abc абв 
+0

彼は 'codecs.open()'を使っています。明示的なエンコーディング/デコードは必要ありません。 – JAB

+0

これで問題は解決しませんが、レッスンに感謝します。これは私が以前に知らなかった非常に興味深い情報です。 –

関連する問題