12

Python2.7.2でUnicodeを処理しようとしています。あることはわかっていますが、.encode('utf-8')追加するとエラーが発生し、追加しないとエラーが発生します。

.encode('utf-8')Pythonに伝える方法はありますか?文字列にUnicodeを使用するだけで、物事をいじくり回す必要がない、最新の現代言語だと思いましたか?

私は知っています...python3.0はこれを行うことになっていますが、3.0は使用できず、2.7はとにかくそれほど古いものではありません...

例えば:

url = "http://en.wikipedia.org//w/api.php?action=query&list=search&format=json&srlimit=" + str(items) + "&srsearch=" + urllib2.quote(title.encode('utf-8'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 19: ordinal not in range(128)

更新.encodeすべてのコードからすべて のステートメントを削除し# -*- coding: utf-8 -*-てファイルの先頭に追加すると、そのすぐ下に、#!/usr/bin/pythonまったく追加しなかった場合と同じように、次のようになり# -*- coding: utf-8 -*-ます。

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py:1250: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
  return ''.join(map(quoter, s))
Traceback (most recent call last):
  File "classes.py", line 583, in <module>
    wiki.getPage(title)
  File "classes.py", line 146, in getPage
    url = "http://en.wikipedia.org/w/api.php?action=query&prop=revisions&format=json&rvprop=content&rvlimit=1&titles=" + urllib2.quote(title)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 1250, in quote
    return ''.join(map(quoter, s))
KeyError: u'\xf1'

私は手動で文字列を入力していません。WebサイトからHTMLとjsonを解析しています。したがって、scripts / bytestreams /それらが何であれ、すべてpythonによって作成されます。

アップデート2エラーを進めることはできますが、新しい場所で発生し続けます。Pythonが便利なスクリプトツールになることを望んでいましたが、3日間運がなかった後は、別の言語を試してみることにします。残念なことに、Pythonはosxにプリインストールされています。投稿したエラーの1つのインスタンスを修正した正解をマークしました。

4

5 に答える 5

18

どこでもユニコード文字列を使用し、受信したエンコードされた文字列をすぐにデコードする以外に、ユニコードを「機能させる」方法はありません。問題は、処理するのがエンコードされたデータであろうとエンコードされていないデータであろうと、またはそれを追跡するツールを使用するかどうかにかかわらず、常にまっすぐにしなければならないことです。

Python 2 は、これに関して問題のあるいくつかのことを行います:文字列リテラルのようなものstrではなく「デフォルト」を作成し、2 つを追加するunicodeと黙って強制strし、既にエンコードされた文字列を呼び出して二重エンコードできるようにします。それ。その結果、多くの python コーダーと python ライブラリがあり、それらはどのエンコーディングで動作するように設計されているかわかりませんが、型はプログラマーが管理できるように設計されているため、特定のエンコーディングを処理するように設計されています。エンコーディング自体。また、これらのライブラリはタイプ自体をサポートしていないため、これらのライブラリを使用するたびにエンコーディングについて考える必要があります。unicode.encode()strunicode


あなたの特定のケースでは、最初のエラーは、エンコードされた UTF-8 データを扱っていて、それを二重エンコードしようとしていることを示していますが、2 番目のエラーは、エンコードされていないデータを扱っていることを示しています。両方を持っている可能性があるようです。問題の原因を実際に見つけて修正する必要があります (上記のサイレント強制に関係していると思われます) が、短期間で修正するハックを次に示します。

encoded_title = title
if isinstance(encoded_title, unicode):
    encoded_title = title.encode('utf-8')

これが実際にあなたを噛んだサイレント強制のケースである場合は、優れたunicode-naziツールを使用して問題を簡単に追跡できるはずです。

python -Werror -municodenazi myprog.py

これにより、実際の問題から離れてこの例外のトラブルシューティングを試みる代わりに、ユニコードが非ユニコード文字列にリークした時点でトレースバックが得られます。詳細については、この関連する質問に対する私の回答を参照してください。

于 2012-09-23T23:52:19.887 に答える
3

はい、Unicode データを Unicode リテラルとして定義します。

>>> u'Hi, this is unicode: üæ'
u'Hi, this is unicode: üæ'

通常、'\uxxxx` Unicode エスケープを使用するか、ソース コード エンコーディングを設定します。たとえば、モジュールの先頭にある次の行は、エンコーディングを UTF-8 に設定します。

# -*- coding: utf-8 -*-

デフォルトのエンコーディングなどの詳細については、Python Unicode HOWTOを参照してください (たとえば、デフォルトのソース コード エンコーディングは ASCII です)。

具体的な例については、タイトルは Unicode リテラルではなく python バイト文字列であり、python はそれunicode にデコードしようとしているので、もう一度エンコードできます。このような自動エンコーディングのデフォルトのコーデックは ASCII であるため、これは失敗します。

>>> 'å'.encode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

エンコーディングは実際の Unicode 文字列にのみ適用されるため、バイト文字列を明示的にデコードする必要があります。

>>> 'å'.decode('utf-8').encode('utf-8')
'\xc3\xa5'

Python 3 に慣れている場合、Python 2 の Unicode リテラル ( u'') は Python 3 の新しいデフォルトの文字列型ですが、Python 2 の通常の (バイト) 文字列 ( ) はPython 3 のオブジェクト( '') と同じです。bytesb''

のエンコード呼び出しの有無にかかわらずエラーがある場合はtitle、データが混在しています。タイトルをテストし、必要に応じてエンコードします。

if isinstance(title, unicode):
    title = title.encode('utf-8')

ただし、ユニコード/バイト文字列が混在するタイトルを生成するものを見つけ、そのソースを修正して、常にどちらか一方を生成することをお勧めします。

于 2012-09-23T23:07:03.447 に答える
2

title.encode("utf-8") のタイトルが Unicode のタイプであることを確認し、str("İŞşĞğÖöÜü") を使用しないでください

stringifiers で unicode("ĞğıIİiÖöŞşcçÇ") を使用します

于 2012-09-23T23:12:27.950 に答える
2

実際、 Python を Unicode で動作させる最も簡単な方法は、デフォルトですべてが Unicode である Python 3 を使用することです。

残念ながら、P3 用に作成されたライブラリは多くなく、コーディングとキーワードの使用にいくつかの基本的な違いがあります。それが私が抱えている問題です: 私が必要とするライブラリは P 2.7 でしか利用できず、それらを P 3 に変換するのに十分な知識がありません. :(

于 2013-02-28T21:34:33.387 に答える