سؤال

أحاول أن أفهم كيف يتعامل بيثون 2.5 مع سلاسل يونيكود. على الرغم من أنني الآن أعتقد أن لدي فهم جيد لكيفية التعامل معها في التعليمات البرمجية، لا أفهم تماما ما يجري وراء الكواليس، خاصة عند كتابة السلاسل في موجه المترجم.

لذلك Python ما قبل 3.0 لديه نوعان من السلاسل، وهي: str (سلاسل البايت) و unicode, ، والتي هي كلاهما مشتق من basestring. وبعد النوع الافتراضي للأسلوت هو str.

str الكائنات ليس لها فكرة ترميزها الفعلي، فهي مجرد بايت. إما أن تقوم بتشفير سلسلة Unicode بنفسك، وبالتالي تعرف على تشفيرها، أو كنت قد قرأت دفقا من البايتات التي تعرف ترميزها مسبقا (بعمق). يمكنك تخمين ترميز سلسلة بايت التي ترميزها غير معروف لك، ولكن هناك طريقة موثوقة لمعرفة ذلك. أفضل رهان هو فك تشفير مبكرا، استخدم Unicode في كل مكان في التعليمات البرمجية الخاصة بك وتشفير متأخرا.

هذا جيّد. ولكن السلاسل المكتوبة في المترجم ترميز بالفعل لك وراء ظهرك؟ شريطة أن يكون فهمي للأسلوت في بيثون هو الصحيح، ما هي الطريقة / الإعدادات التي يستخدمها Python لجعل هذا القرار؟

مصدر ارتباكي هو النتائج المختلفة التي أحصل عليها عندما أحاول نفس الشيء على تثبيت Python في النظام الخاص بي، وعلى وحدة تحكم Python المدمجة في المحرر.

 # Editor (Sublime Text)
 >>> s = "La caña de España"
 >>> s
 'La ca\xc3\xb1a de Espa\xc3\xb1a'
 >>> s.decode("utf-8")
 u'La ca\xf1a de Espa\xf1a'
 >>> sys.getdefaultencoding()
 'ascii'

 # Windows python interpreter
 >>> s= "La caña de España"
 >>> s
 'La ca\xa4a de Espa\xa4a'
 >>> s.decode("utf-8")
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "C:\Python25\lib\encodings\utf_8.py", line 16, in decode
     return codecs.utf_8_decode(input, errors, True)
 UnicodeDecodeError: 'utf8' codec can't decode byte 0xa4 in position 5: unexpected code byte
 >>> sys.getdefaultencoding()
 'ascii'
هل كانت مفيدة؟

المحلول

اسمحوا لي أن توسع ردا ignacio: في كلتا الحالتين هناك طبقة إضافية بين بيثون وأنت: في حالة واحدة نص سامي وفي الآخر هو cmd.exe. وبعد الفرق في السلوك الذي تراه ليس بسبب Python ولكن بواسطة الترميزات المختلفة المستخدمة من قبل نص سامي (UTF-8، كما يبدو) و cmd.exe (CP437).

لذلك، عند الكتابة ñ, نص سامي يرسل '\xc3\xb1' إلى بايثون، في حين cmd.exe يرسل \xa4. وبعد [أنا ببساطة هنا، حذف التفاصيل التي ليست ذات صلة بالسؤال.].

ومع ذلك، فإن بيثون يعرف ذلك. من عند cmd.exe ربما تحصل على شيء مثل:

>>> import sys
>>> sys.stdin.encoding
'cp437'

بينما داخل نص سامي سوف تحصل على شيء مثل

>>> import sys
>>> sys.stdin.encoding
'utf-8'

نصائح أخرى

يستخدم المترجم الترميز الأصلي لترميز موجه الخاص بك لإدخال النص. في حالتك، إنها CP437:

>>> print '\xa4'.decode('cp437')
ñ

تشعر بالارتباك لأن المحرر والترجمي يستخدم ترميزات مختلفة أنفسهم. يستخدم مترجم Python الافتراضي للنظام (في هذه الحالة، cp437)، في حين أن محرر الخاص بك يستخدم utf-8.

ملاحظة، يختفي الفرق إذا حددت سلسلة Unicode، مثل ذلك:

# Windows python interpreter
>>> s = "La caña de España"
>>> s
'La ca\xa4a de Espa\xa4a'
>>> s = u"La caña de España"
>>> s
u'La ca\xf1a de Espa\xf1a'

العظة من القصة؟ الترميزات صعبة. تأكد من أنك تعرف ما هو ترميز ملفاتك المصدر، أو تشغيله بأمان دائما باستخدام الإصدار المتفجر من الأحرف الخاصة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top