Python UTF-8 مقارنة
-
25-09-2019 - |
سؤال
a = {"a":"çö"}
b = "çö"
a['a']
>>> '\xc3\xa7\xc3\xb6'
b.decode('utf-8') == a['a']
>>> False
ماذا يحدث هناك؟
تحرير = أنا آسف ، لقد كان خطأي. لا تزال خاطئة. أنا أستخدم Python 2.6 على Ubuntu 10.04.
المحلول
الحلول الممكنة
إما أن تكتب هكذا:
a = {"a": u"çö"}
b = "çö"
b.decode('utf-8') == a['a']
أو مثل هذا (يمكنك أيضًا تخطي .decode('utf-8')
على كلا الجانبين):
a = {"a": "çö"}
b = "çö"
b.decode('utf-8') == a['a'].decode('utf-8')
أو مثل هذا (توصيتي):
a = {"a": u"çö"}
b = u"çö"
b == a['a']
تفسير
تم تحديثه بناءً على تعليق تيم. في الكود الأصلي الخاص بك ، b.decode('utf-8') == u'çö'
و a['a'] == 'çö'
, ، لذلك أنت في الواقع تقوم بالمقارنة التالية:
u'çö' == 'çö'
أحد الكائنات من النوع unicode
, والآخر من النوع str
, ، لذلك من أجل تنفيذ المقارنة ، str
يتم تحويله إلى unicode
ثم الاثنين unicode
تتم مقارنة الكائنات. إنه يعمل بشكل جيد في حالة سلاسل ASCII بحتة ، على سبيل المثال: u'a' == 'a'
, ، حيث unicode('a') == u'a'
.
ومع ذلك ، فإنه يفشل في حالة u'çö' == 'çö'
, ، حيث unicode('çö')
إرجاع الخطأ التالي: UnicodedEcodeerror: لا يمكن لترميز "ASCII" فك تشفير البايت 0xc3 في الموضع 0: ترتيبي ليس في النطاق (128), وبالتالي فإن المقارنة بأكملها تعود كاذبة وتتمكن من التحذير التالي: Unicodewarning: فشلت المقارنة المتساوية Unicode في تحويل كلتا الوسيطتين إلى Unicode - فورفهما على أنه غير متكافئ.
نصائح أخرى
b
هو string
, a
هو dict
تريد (أعتقد):
b == a['a']
UTF-8 هو ترميز يستخدم لتسجيل نص Unicode في الملفات. ومع ذلك ، في Python ، تعمل مع كائنات لها طريقة ثابتة لتمثيل نص Unicode ، وبهذه الطريقة ليست UTF-8.
لا يزال بإمكانك مقارنة سلاسل Unicode في Python ، ولكن هذا لا علاقة له بـ UTF-8 ، باستثناء أنه إذا كنت ترغب في وضع الثوابت في هذه السلاسل الأحادية ، فستحتاج إلى تشفير نص الملف الذي يحتوي على رمز المصدر الخاص بك ، في UTF- 8. بمجرد تنفيذ مشغل المهمة ، لم تعد السلسلة UTF-8 ، ولكنها الآن تمثل بيثون الداخلي.
بالمناسبة ، إذا كنت تقوم بمقارنات مع Unicode ، فربما ترغب في استخدام وحدة Unicodedata وتطبيع السلاسل قبل إجراء المقارنات.
جرب B == A ['A'
أنت تقارن سلسلة بقول.
>>> a = {"a":"çö"}
>>> b = "çö"
>>> a == b
False
>>> a['a'] == b
True
إذا قارنت السلسلة (ب) بعضو A (A [A ']) ، فستحصل على النتيجة المرجوة.
تأكد من أن الكود الخاص بك في UTF-8 (وليس لاتيني 1) و/أو استخدم خط الترميز كما هو الحال:
#! /usr/bin/python
# -*- coding: utf-8 -*-
a = {"a": u"çö"}
b = "çö"
assert b == a['a']
assert b.decode('utf-8') == a['a'].decode('utf-8')
إذا كنت تستخدم Unicode عبر اللوحة ، فيمكنك استيراد Unicode_Literals من المستقبل وتقليص آلام القلب:
#! /usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
a = {"a": u"çö"}
b = "çö"
assert b == a['a']
assert b == a['a']
assert b.encode('utf-8') != a['a']
assert b.encode('utf-8') == a['a'].encode('utf-8')
إذا كان الملف يستخدم Unicode_Literals ، فإن جميع "الأوتار" هي الآن كائنات Unicode "(وفقًا لترميز الملف) إذا لم تكن B" مسبقًا "مع AB (لمحاكاة السلسلة/البايتات في Python 3.x) .
Nulluserexception محق في أن هذا يجب أن يكون صحيحًا:
b == a['a']
لا تزال تحصل على "خطأ" لأنك تفكك جانبًا كـ UTF-8 (إنشاء سلسلة Unicode) بينما يظل الجانب الآخر عبارة عن سلسلة بايت مشفرة UTF-8.