سؤال

أنا أعمل على بعض الكود الذي يتعامل مع سلاسل يونيكود. أحاول كتابة مستندات لذلك، لكن أواجه مشكلة. ما يلي هو مثال ضئيل يوضح المشكلة:

# -*- coding: utf-8 -*-
def mylen(word):
  """
  >>> mylen(u"áéíóú")
  5
  """
  return len(word)

print mylen(u"áéíóú")

أولا، ندير التعليمات البرمجية لرؤية الناتج المتوقع print mylen(u"áéíóú").

$ python mylen.py
5

بعد ذلك، ندير Doctest عليه لرؤية المشكلة.

$ python -m
5
**********************************************************************
File "mylen.py", line 4, in mylen.mylen
Failed example:
    mylen(u"áéíóú")
Expected:
    5
Got:
    10
**********************************************************************
1 items had failures:
   1 of   1 in mylen.mylen
***Test Failed*** 1 failures.

كيف يمكنني ذلك يمكنني اختبار ذلك mylen(u"áéíóú") يقيم إلى 5؟

هل كانت مفيدة؟

المحلول

إذا كنت تريد سلاسل يونيكود، عليك استخدام unicode docStrings! مانع u!

# -*- coding: utf-8 -*-
def mylen(word):
  u"""        <----- SEE 'u' HERE
  >>> mylen(u"áéíóú")
  5
  """
  return len(word)

print mylen(u"áéíóú")

هذا سيعمل - طالما أن الاختبارات تمر. بالنسبة إلى Python 2.x، فأنت بحاجة إلى اختراق آخر لجعل وضع الوقود المطلي أو الحصول على Tracebacks الصحيح عند فشل الاختبارات:

if __name__ == "__main__":
    import sys
    reload(sys)
    sys.setdefaultencoding("UTF-8")
    import doctest
    doctest.testmod()

ملحوظ فقط استخدم SetDefaultEncoding فقط لأغراض التصحيح. أقبل ذلك لاستخدام المستندات، ولكن ليس في أي مكان في رمز الإنتاج الخاص بك.

نصائح أخرى

Python 2.6.6 لا يفهم إنتاج يونيكود جيدا، ولكن يمكن إصلاح هذا باستخدام:

  • وصف بالفعل الاختراق مع sys.setdefaultencoding("UTF-8")
  • Unicode Docstring (المذكورة بالفعل أعلاه أيضا، شكرا جزيلا)
  • و print بيان.

في حالتي، يخبر هذا المستند أن الاختبار مكسور:

def beatiful_units(*units):
    u'''Returns nice string like 'erg/(cm² sec)'.

    >>> beatiful_units(('erg', 1), ('cm', -2), ('sec', -1))
    u'erg/(cm² sec)'
    '''

مع رسالة "خطأ"

Failed example:
    beatiful_units(('erg', 1), ('cm', -2), ('sec', -1))
Expected:
    u'erg/(cm² sec)'
Got:
    u'erg/(cm\xb2 sec)'

استخدام print يمكننا إصلاح ذلك:

def beatiful_units(*units):
    u'''Returns nice string like 'erg/(cm² sec)'.

    >>> print beatiful_units(('erg', 1), ('cm', -2), ('sec', -1))
    erg/(cm² sec)
    '''

يبدو أن هذا هو مسألة معروفة وغير مرتبطة حتى الآن في بيثون. انظر القضايا المفتوحة هنا و هنا.

ليس من المستغرب أن يتم تعديلها للعمل موافق في بيثون 3 لأن جميع السلاسل هي Unicode هناك:

def mylen(word):
  """
  >>> mylen("áéíóú")
  5
  """
  return len(word)

print(mylen("áéíóú"))

كان الحل الخاص بي هو الهروب من أحرف Unicode، مثل U ' XE1 XE9 XED XF3 XFA'. لم يكن الأمر سهلا للقراءة، لكن اختباراتي تحتوي فقط على عدد قليل من أحرف غير أسكي حتى في تلك الحالات وضعت الوصف على الجانب كتعليق، مثل "# N مع تيلدة".

كما ذكرنا بالفعل، تحتاج إلى ضمان rocstrings الخاص بك هي Unicode.

إذا كنت تستطيع التبديل إلى Python 3، فسوف يعمل تلقائيا هناك، كما على حد سواء الترميز المصدر هو بالفعل UTF-8 ونوع السلسلة الافتراضية هو Unicode.

لتحقيق نفس الشيء في بيثون 2، تحتاج إلى الحفاظ على coding: utf-8 التالي الذي يمكنك إما بادئة جميع المستندات u, ، أو ببساطة إضافة

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