4

Python は強く型付けされているはずです。

たとえば'abc'['1']、文字列ではなく整数を指定する必要があるため、機能しません。エラーが発生し、続行して修正できます。

しかし、hashlib はそうではありません。実際、次のことを試してください。

import hashlib
hashlib.md5('abc') #Works OK        

hashlib.md5(1) 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: md5() argument 1 must be string or read-only buffer, not int

hashlib.md5(u'abc') #Works, but shouldn't : this is unicode, not str.

haslib.md5(u'é')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 0: ordinal not in range(128)

もちろん、 が原因で失敗するのではなくTypeError、 が原因で失敗しUnicodeEncodeErrorます。UnicodeEncodeErrorUnicode を文字列にエンコードしようとすると発生するはずです。

私の推測では、Hashlib が静かに Unicode を文字列に変換しようとしたので、私は真実からそれほど遠くないと思います。

今。同意します。hashlib は、への引数がhashlib.md5()文字列または読み取り専用バッファ (Unicode 文字列) である必要があることを示しました。しかし、これは実際にはそうではないことを示していhashlib.md5()ます。文字列で適切に機能し、それだけです。

もちろん、これが引き起こす主な問題は、一部の Unicode 文字列では例外が発生し、他の一部では例外が発生しないことです。

それが私の質問につながります。まず、hashlib がこの動作を実装する理由について説明がありますか? 第二に、それは問題と見なされますか? 第三に、モジュール自体を変更せずにこれを修正する方法はありますか?

Hashlib は基本的には例です。Unicode 文字列を指定すると同じように動作するモジュールが他にもいくつかあります。これにより、プログラムが ASCII 入力では機能するが、アクセントで完全に失敗するという不快な状況が発生します。

4

2 に答える 2

12

hashlib だけではありません。Python 2 は、Unicode を ascii としてエンコードしようとすることで、多くの場所で Unicode を処理します。これは、Python 3 で行われた大きな変更の 1 つです。

Python 3 では、文字列は Unicode であり、期待どおりに動作します。バイトへの自動変換はなく、バイトを使用する場合 (MD5 ハッシュなど) はエンコードする必要があります。Python 2 でこの動作を可能にするハックsys.setdefaultencodingがあると思いますが、その Python インスタンスで実行されているコードに影響を与えるため、本番環境では使用しないことをお勧めします。

于 2011-08-01T16:50:21.517 に答える
2

これは、Python 2.x C API により、Unicode オブジェクトを C API に渡して文字列を受け取るのが便利になった結果です。

_hashopenssl.cの PyArg_ParseTuple* 呼び出しを参照してください。

's*' 引数を解析するときに、Unicode オブジェクトをバイト文字列にエンコードしようとします。エンコードできない場合、エラーが発生します。生のバイト ストリームのみが意味を持つコンテキストで Unicode を使用しようとする前に、常に .encode('utf-8') またはアプリケーションが必要とするその他のコーデックを呼び出すのが正しい方法です。

Python 3.x ではこれが修正されています。代わりに、常にフレンドリーを取得します。

TypeError: ハッシュする前に Unicode オブジェクトをエンコードする必要があります

自動エンコードの代わりに。

于 2012-01-22T06:46:48.277 に答える