2011-12-21 3 views
4

は、この関数を考えてみましょう:私はstr.decode()を行っていますが、PythonはUnicodeEncodeErrorをスローします。どうして?

def escape(text): 
    print repr(text) 
    escaped_chars = [] 
    for c in text: 
     try: 
      c = c.decode('ascii') 
     except UnicodeDecodeError: 
      c = '&{};'.format(htmlentitydefs.codepoint2name[ord(c)]) 
     escaped_chars.append(c) 
    return ''.join(escaped_chars) 

それは、対応するhtmlentitydefsにより、すべての非ASCII文字をエスケープする必要があります。変数textはそのrepr()u'Tam\xe1s Horv\xe1th'ある文字列が含まれている場合、残念ながら、Pythonは

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 0: ordinal not in range(128) 

をスローします。

しかし、str.encode()は使用しません。私はstr.decode()を使用します。私は何かが恋しいですか?

答えて

2

Pythonは二つの文字列の種類を持って確認することができると思います。貼り付けたコードは、バイト列で処理されます。文字列を扱うには、同様の関数が必要です。

多分これ:

def uescape(text): 
    print repr(text) 
    escaped_chars = [] 
    for c in text: 
     if (ord(c) < 32) or (ord(c) > 126): 
      c = '&{};'.format(htmlentitydefs.codepoint2name[ord(c)]) 
     escaped_chars.append(c) 
    return ''.join(escaped_chars) 

私はどちらかの機能があなたのために本当に必要かどうかを疑問に思うん。私の場合は、結果ドキュメントの文字エンコーディングとしてUTF-8を選択し、エンティティを心配することなく文字列形式でドキュメントを処理し、最後のステップとしてcontent.encode('UTF-8')を実行してからクライアントに配信します。選択したWebフレームワークに応じて、文字列を直接APIに渡して、エンコーディングの設定方法を理解できるようにすることさえできます。

5

すでにユニコードの文字列を渡しています。したがって、Pythonがdecodeを呼び出す前に、実際にはそれをエンコードする必要があります。デフォルトでは、ASCIIエンコーディングを使用しています。

あなたが何をしたいかによって異なります。非ASCII文字を含むUnicode文字列をHTMLエンコードされた表現に変換するだけの場合は、1回の呼び出しでそれを行うことができます:text.encode('ascii', 'xmlcharrefreplace')

+0

で解決策を見つけましたか? – Aufwind

+0

または、ナンセンス文字をエスケープする私のアプローチですか? – Aufwind

-2

decodea str意味がありません。文字列(unicodeタイプ)とバイト文字列(strタイプ):

は、私はあなたがord(c)>127

11

これは、pythonがde/encodingプロセスを処理する方法に由来する誤解を招くエラーレポートです。あなたは既にデコードされたStringをもう一度デコードしようとしましたが、これは順番にあなたを混乱させて報復するPythonの機能を混乱させます! ;-)符号化/復号化プロセスは、私が知っている限り、codecs-moduleによって行われます。そして、この誤解を招く例外メッセージの原点がどこかにあります。

あなたは自分のためにチェックすることがあります。

u'\x80'.encode('ascii') 

または

u'\x80'.decode('ascii') 

いずれか

u'\x80'.encode('utf8') 

はありませんが、

ユニコード エンコードエラーをスローします
u'\x80'.decode('utf8') 

もう一度!

私はあなたがエンコードとデコードの意味で混乱していると思います。シンプルに言えば :

     decode    encode  
ByteString (ascii) --------> UNICODE ---------> ByteString (utf8) 
      codec            codec 

しかし、なぜdecode方法についてcodec -argumentがありますか?さて、基礎となる関数は、ByteStringがどのコーデックでエンコードされているかを推測することができないので、ヒントとしてcodecを引数にとります。提供されていない場合は、暗黙的に使用されることを意味します(sys.getdefaultencoding())。

c.decode('ascii')を使用すると、a)(エンコードされた)ByteString(デコードを使用する理由)b)ユニコード表現オブジェクト(デコードを使用するもの)を取得したい、c)コーデックByteStringがエンコードされているのはasciiです。

も参照してください: https://stackoverflow.com/a/370199/1107807
http://docs.python.org/howto/unicode.html
http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
http://www.stereoplex.com/blog/python-unicode-and-unicodedecodeerror

+0

この詳細な説明をありがとうございます。 – Aufwind

1

私はこの問題を持っている場合は、この答えはいつも私の作品:

def byteify(input): 
    ''' 
    Removes unicode encodings from the given input string. 
    ''' 
    if isinstance(input, dict): 
     return {byteify(key):byteify(value) for key,value in input.iteritems()} 
    elif isinstance(input, list): 
     return [byteify(element) for element in input] 
    elif isinstance(input, unicode): 
     return input.encode('utf-8') 
    else: 
     return input 

How to get string objects instead of Unicode ones from JSON in Python?

0
から

私はあなたが私も、UnicodeEncodeErrorををキャッチしなければならないわけthis-site

 
reload(sys) 
sys.setdefaultencoding("latin-1") 

a = u'\xe1' 
print str(a) # no exception 
関連する問題