55

これが私のエラーメッセージの試みです。私は何を間違っていますか?

string.decode("ascii", "ignore")

UnicodeEncodeError: 'ascii' コーデックは位置 37 の文字 u'\xa0' をエンコードできません: 序数が範囲内にありません(128)

string.encode('utf-8', "ignore")

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

4

4 に答える 4

87

をデコードすることはできません。unicodeまた、をエンコードすることもできませんstr逆にやってみてください。

于 2012-07-05T07:50:15.767 に答える
61

元の質問から省略されたすべてのものを推測しますが、Python 2.xを想定すると、キーはエラーメッセージを注意深く読むことです.メッセージに含まれる値の型。

最初の例stringはタイプであり、バイト文字列ユニコードにunicode変換する操作であるデコードを試みました。Python は、Unicode 値をデフォルトの 'ascii' エンコーディングを使用するように変換しようとしましたが、文字列に非 ASCII 文字が含まれていたため、Python がunicode値をエンコードできなかったというエラーが表示されました。入力文字列のタイプを示す例を次に示します。str

>>> u"\xa0".decode("ascii", "ignore")

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    u"\xa0".decode("ascii", "ignore")
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 0: ordinal not in range(128)

2 番目のケースでは、逆の方法でバイト文字列をエンコードしようとします。エンコーディングは、Unicode をバイト文字列に変換する操作であるため、Python は最初にバイト文字列を Unicode に変換しようとします。ASCII 文字列を指定しなかったため、デフォルトの ascii デコーダーは失敗します。

>>> "\xc2".encode("ascii", "ignore")

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    "\xc2".encode("ascii", "ignore")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128)
于 2012-07-05T11:02:38.573 に答える
28

取得decodeencode逆戻りは別として、ここでの答えの一部は、実際にはエンコーディングを使用しないことasciiだと思います。それはおそらくあなたが望むものではありません。

まずstr、プレーン テキスト ファイルと同じように考えてください。実際にはエンコーディングが付加されていない単なるバイトの集まりです。それがどのように解釈されるかは、それを読み取るコードの一部に依存します。この段落が何について話しているのかわからない場合は、先に進む前に、Joel のThe Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Setsを今すぐ読んでください。

当然のことながら、私たちは皆、混乱が生じたことを認識しています。答えは、少なくともメモリ内で、すべての文字列に対して標準のエンコーディングを用意することです。Python が内部で使用しているエンコーディングを正確に追跡するのに苦労していますが、これunicodeだけでは問題になりません。ポイントは、特定の方法で解釈される一連のバイトであることを知っていることです。したがって、バイトではなく、文字自体について考える必要があります。

問題は、実際には両方に遭遇することです。を提供するライブラリもあれば、strを期待するライブラリもありますstr。確かに、一連のバイトをストリーミングしている場合 (ディスクとの間、または Web 要求を介して) は常に意味があります。そのため、前後に翻訳できる必要があります。

Enter codecs: これら 2 つのデータ型の間の変換ライブラリです。を使用してテキスト文字列 ( )から一連のバイト ( )encodeを生成し、 を使用して一連のバイト ( str) からテキスト文字列 ( unicode)decodeを取得します。unicodestr

例えば:

>>> s = "I look like a string, but I'm actually a sequence of bytes. \xe2\x9d\xa4"
>>> codecs.decode(s, 'utf-8')
u"I look like a string, but I'm actually a sequence of bytes. \u2764"

ここで何が起こったのですか?私は Python に一連のバイトを渡し、「unicodeこの一連のバイトが'utf-8'. 私が要求したとおりに実行され、これらのバイト (ハート文字) は全体として扱われ、Unicode コードポイントで表されます。

逆に行きましょう:

>>> u = u"I'm a string! Really! \u2764"
>>> codecs.encode(u, 'utf-8')
"I'm a string! Really! \xe2\x9d\xa4"

'utf-8'私は Python に Unicode 文字列を与え、エンコーディングを使用して文字列を一連のバイトに変換するように依頼しました。そうしました、そして今、ハートはASCIIとして印刷できない単なるバイトの集まりです。そのため、代わりに16進数が表示されます。

もちろん、他のエンコーディングも使用できます。

>>> s = "I have a section \xa7"
>>> codecs.decode(s, 'latin1')
u'I have a section \xa7'
>>> codecs.decode(s, 'latin1')[-1] == u'\u00A7'
True

>>> u = u"I have a section \u00a7"
>>> u
u'I have a section \xa7'
>>> codecs.encode(u, 'latin1')
'I have a section \xa7'

('\xa7'は、Unicode と Latin-1 の両方のセクション文字です。)

したがって、あなたの質問については、まず自分のエンコーディングを把握する必要がありますstr

  • それはファイルから来ましたか?ウェブリクエストから?あなたのデータベースから?次に、ソースがエンコーディングを決定します。ソースのエンコーディングを調べ、それを使用してunicode.

    s = [get from external source]
    u = codecs.decode(s, 'utf-8') # Replace utf-8 with the actual input encoding
    
  • または、どこかに書き込もうとしているのかもしれません。宛先はどのエンコーディングを期待していますか? それを使用して、に変換しstrます。UTF-8 はプレーン テキスト ドキュメントに適しています。ほとんどのものはそれを読むことができます。

    u = u'My string'
    s = codecs.encode(u, 'utf-8') # Replace utf-8 with the actual output encoding
    [Write s out somewhere]
    
  • 相互運用性などのためにメモリ内で前後に変換しているだけですか? 次に、エンコーディングを選択して、それに固執します。'utf-8'おそらくそのための最良の選択です:

    u = u'My string'
    s = codecs.encode(u, 'utf-8')
    newu = codecs.decode(s, 'utf-8')
    

'ascii'現代のプログラミングでは、おそらくこれにエンコーディングを使用したくないでしょう。これは可能なすべての文字の非常に小さなサブセットであり、私が知っているシステムでデフォルトなどで使用されているものはありません。

Python 3 は、名前を変更するだけでこれを非常に明確にするために最善を尽くしています。Python 3 では、strが に置き換えられbytesunicodeが に置き換えられましたstr

于 2014-08-08T23:05:56.237 に答える
2

これは、入力文字列をエンコード規則(デフォルトでは厳密)に従って変換できないためです。

わかりませんが、私は常にunicode()コンストラクターを直接使用してエンコードしました。少なくとも、公式ドキュメントではその方法です。

unicode(your_str, errors="ignore")
于 2012-07-05T07:58:02.163 に答える