Pythonでのunicode()およびencode()関数の使用


83

パス変数のエンコードとSQLiteデータベースへの挿入に問題があります。役に立たなかったencode( "utf-8")関数でそれを解決しようとしました。次に、タイプunicodeを与えるunicode()関数を使用しました。

print type(path)                  # <type 'unicode'>
path = path.replace("one", "two") # <type 'str'>
path = path.encode("utf-8")       # <type 'str'> strange
path = unicode(path)              # <type 'unicode'>

最終的にUnicodeタイプを取得しましたが、パス変数のタイプがstrの場合と同じエラーが発生します。

sqlite3.ProgrammingError:8ビットバイトストリングを解釈できるtext_factory(text_factory = strなど)を使用しない限り、8ビットバイトストリングを使用しないでください。代わりに、アプリケーションをUnicode文字列に切り替えることを強くお勧めします。

このエラーを解決しencode("utf-8")unicode()機能の正しい使用法を説明するのを手伝ってもらえますか?私はよくそれと戦っています。

編集:

このexecute()ステートメントはエラーを引き起こしました:

cur.execute("update docs set path = :fullFilePath where path = :path", locals())

同じ問題を抱えているfullFilePath変数のエンコーディングを変更するのを忘れましたが、今はかなり混乱しています。unicode()またはencode( "utf-8")、あるいはその両方のみを使用する必要がありますか?

使えない

fullFilePath = unicode(fullFilePath.encode("utf-8"))

このエラーが発生するため:

UnicodeDecodeError: 'ascii'コーデックは32桁目のバイト0xc5をデコードできません:序数がrange(128)にありません

Pythonのバージョンは2.7.2です


エラーを発生させるコードはどこにありますか?
newtover 2012

2
あなたの正確な質問が既に回答されています[ stackoverflow.com/questions/2392732/... [1]:stackoverflow.com/questions/2392732/...
garnertb

@newtover質問を編集しました。
xralf 2012

両方の使用変数をに変換しましたunicodeか?
newtover 2012

2
Python 3テキストとデータをどのように処理するかを学ぶことは、私がすべてを理解するのに本当に役立ちました。Python 2に知識を適用するために、その後は簡単です
オレグPrypin

回答:


87

encode("utf-8")間違って使用しています。Pythonのバイト文字列(strタイプ)にはエンコードがありますが、Unicodeにはありません。を使用してUnicode文字列をPythonバイト文字列にuni.encode(encoding)変換できます。またs.decode(encoding)、(または同等にunicode(s, encoding))を使用してバイト文字列をUnicode文字列に変換できます。

場合fullFilePathpath現在strのタイプ、あなたは彼らがエンコードされている方法を見つけ出す必要があります。たとえば、現在のエンコーディングがutf-8の場合、次を使用します。

path = path.decode('utf-8')
fullFilePath = fullFilePath.decode('utf-8')

これで修正されない場合、実際の問題は、execute()呼び出しでUnicode文字列を使用していないことである可能性があります。次のように変更してみてください。

cur.execute(u"update docs set path = :fullFilePath where path = :path", locals())

このステートメントでfullFilePath = fullFilePath.decode("utf-8")もエラーが発生しますUnicodeEncodeError: 'ascii' codec can't encode characters in position 32-34: ordinal not in range(128)。fullFilePathは、タイプstrと、データベーステーブルのテキスト列から取得した文字列の組み合わせであり、utf-8エンコーディングである必要があります。
xralf 2012

これによると UTF-8、UTF-16BE、またはUTF-16LEの場合があります。どういうわけかそれを見つけることができますか?
xralf 2012

@ xralf、異なるstrオブジェクトを組み合わせる場合は、エンコーディングを混合している可能性があります。結果を見せていただけますprint repr(fullFilePath)か?
アンドリュークラーク

decode()を呼び出す前にのみ表示できます。問題のある文字は\ u016​​1と\ u016​​5です。
xralf 2012

@ xralf-それで、それはすでにユニコードですか?:unicodeに呼び出しを実行変更してみてくださいcur.execute(u"update docs set path = :fullFilePath where path = :path", locals())
アンドリュー・クラーク

121

strはバイト単位のテキスト表現、unicodeは文字単位のテキスト表現です。

テキストをバイトからユニコードにデコードし、ユニコードを何らかのエンコードでバイトにエンコードします。

あれは:

>>> 'abc'.decode('utf-8')  # str to unicode
u'abc'
>>> u'abc'.encode('utf-8') # unicode to str
'abc' 

1
非常に良い答えです。私は追加したいunicode文字や記号について話す、またはより一般的に:ルーンをしながら、str表しあなたがしなければならないこと、特定のエンコードで文字列をバイトdecode特定のルーンを取得するには(明らかに正しいエンコーディングで)
arainone

1

シェルからスクリプトを実行する直前に、ロケール設定を設定していることを確認してください。

$ locale -a | grep "^en_.\+UTF-8"
en_GB.UTF-8
en_US.UTF-8
$ export LC_ALL=en_GB.UTF-8
$ export LANG=en_GB.UTF-8

ドキュメント:man localeman setlocale

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.