استخدام وظائف unicode () و encode () في Python

سئل على ٢٣ أبريل ٢٠١٢  ·  تمت مشاهدة 271.9k مرة  ·  مصدر

xralf picture
في ٢٣ أبريل ٢٠١٢

لدي مشكلة في ترميز متغير المسار وإدراجه في قاعدة بيانات SQLite . حاولت حلها باستخدام وظيفة التشفير ("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 يمكنه تفسير سلاسل بايت 8 بت (مثل text_factory = str). يوصى بشدة بتبديل تطبيقك بدلاً من ذلك إلى سلاسل Unicode.

هل يمكنك مساعدتي في حل هذا الخطأ وشرح الاستخدام الصحيح للوظائف encode("utf-8") و unicode() ؟ غالبًا ما أقاتل معها.

تعديل:

أثارت عبارة التنفيذ هذه

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

لقد نسيت تغيير ترميز متغير fullFilePath الذي يعاني من نفس المشكلة ، لكنني في حيرة من unicode () فقط أو التشفير ("utf-8") أو كليهما؟

لا يمكنني استخدام

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

لأنه يثير هذا الخطأ:

خطأ UnicodeDecode: لا يمكن لبرنامج الترميز 'ascii' فك تشفير البايت 0xc5 في الموضع 32: الترتيب الترتيبي ليس في النطاق (128)

إصدار Python هو 2.7.2

الإجابات

newtover picture
في ٢٣ أبريل ٢٠١٢
122

str تمثيل نصي بالبايت ، unicode تمثيل نصي بالأحرف.

تقوم بفك تشفير النص من بايت إلى يونيكود وترميز unicode إلى بايت مع بعض الترميز.

هذا هو:

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

تحديث سبتمبر 2020 : تمت كتابة الإجابة عندما تم استخدام Python 2 في الغالب. في Python 3 ، تمت إعادة تسمية str إلى bytes ، وتمت إعادة تسمية unicode إلى str .

>>> b'abc'.decode('utf-8') # bytes to str
'abc'
>>> 'abc'.encode('utf-8'). # str to bytes
b'abc'
Andrew Clark picture
في ٢٣ أبريل ٢٠١٢
87

أنت تستخدم encode("utf-8") بشكل غير صحيح. سلاسل بايت Python (نوع str ) لها ترميز ، لكن Unicode لا. يمكنك تحويل سلسلة Unicode إلى سلسلة Python بايت باستخدام uni.encode(encoding) ، ويمكنك تحويل سلسلة بايت إلى سلسلة Unicode باستخدام s.decode(encoding) (أو ما يعادله ، unicode(s, encoding) ).

إذا كان fullFilePath و path النوع str ، يجب عليك معرفة كيفية تشفيرهما. على سبيل المثال ، إذا كان الترميز الحالي هو utf-8 ، يمكنك استخدام:

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

إذا لم يؤد ذلك إلى حل المشكلة ، فقد تكون المشكلة الفعلية هي أنك لا تستخدم سلسلة Unicode في مكالمتك execute() ، فحاول تغييرها إلى ما يلي:

cur.execute(u"update docs set path = :fullFilePath where path = :path", locals())
kenorb picture
في ٢٦ سبتمبر ٢٠١٧
1

تأكد من ضبط الإعدادات المحلية الخاصة بك قبل تشغيل البرنامج النصي من shell ، على سبيل المثال

$ 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 locale ، man setlocale .