سؤال

لدي هذا:

>>> print 'example'
example
>>> print 'exámple'
exámple
>>> print 'exámple'.upper()
EXáMPLE

ما يجب أن أفعله للطباعة:

EXÁMPLE

(حيث يحصل "A" عن إجازاته، ولكن في أحرف كبيرة).

أنا أستخدم بيثون 2.6.

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

المحلول

أعتقد أنها بسيطة مثل ليس تحويل إلى ASCII أولا.

 >>> print u'exámple'.upper()
 EXÁMPLE

نصائح أخرى

في بيثون 2.x، فقط قم بتحويل السلسلة إلى Unicode قبل الاتصال العلوي (). استخدام التعليمات البرمجية الخاصة بك، وهو بتنسيق UTF-8 في صفحة الويب هذه:

>>> s = 'exámple'
>>> s
'ex\xc3\xa1mple'  # my terminal is not utf8. c3a1 is the UTF-8 hex for á
>>> s.decode('utf-8').upper()
u'EX\xc1MPLE'  # c1 is the utf-16 aka unicode for á

دعوة إلى decode يأخذها من تنسيقها الحالي إلى Unicode. يمكنك بعد ذلك تحويله إلى تنسيق آخر، مثل UTF-8، باستخدام الترميز. إذا كانت الشخصية، قل، ISO-8859-2 (جمهورية التشيك، إلخ، في هذه الحالة)، سوف تستخدم بدلا من ذلك s.decode('iso-8859-2').upper().

كما هو الحال في حالتي، إذا لم تكن المحطة الطرفية الخاصة بك متوافقة مع UNICODE / UTF-8، فإن أفضل ما يمكن أن نأمله هو تمثيل سداسي عشري للشخصيات (مثل Mine) أو لتحويله باستخدام ضيافة باستخدام s.decode('utf-8').upper().encode('ascii', 'replace'), ، مما يؤدي إلى "السابقين". إذا لم تتمكن من إظهار محطة Unicode الخاصة بك، فقم بكتابة الإخراج إلى ملف بتنسيق UTF-8 وفتح ذلك في المحرر المفضل لديك.

أولا، أنا فقط استخدم بيثون 3.1 هذه الأيام؛ الجدارة المركزية لها هي أن تزعج سلاسل البايت من كائنات Unicode. هذا يجعل الغالبية العظمى من التلاعب النص أكثر أمانا مما كان عليه الحال. يزن في تريليونات أسئلة المستخدم بخصوص مشاكل ترميز Python 2.x، u'äbc كان اتفاقية بيثون 2.1 خطأ؛ مع صريح. bytes و bytearray, ، تصبح الحياة أسهل بكثير.

ثانيا، إذا كان PY3K ليس نكهك، فحاول الذهاب مع from __future__ import unicode_literals, ، نظرا لأن هذا سوف تقليد سلوك PY3K على Python 2.6 و 2.7. كان هذا الشيء قد تجنب خطأ (الملتزم بسهولة) فعلت عندما يقول print 'exámple'.upper() وبعد أساسا، هذا هو نفسه كما هو الحال في PY3K: print( 'exámple'.encode( 'utf-8' ).upper() ). وبعد قارن هذه الإصدارات (ل PY3K):

print( 'exámple'.encode( 'utf-8' ).upper() )
print( 'exámple'.encode( 'utf-8' ).upper().decode( 'utf-8' ) )
print( 'exámple'.upper() )

أول واحد هو، أساسا، ما فعلت عند استخدام سلسلة عارية 'exámple', ، شريطة أن تحدد الترميز الافتراضي الخاص بك utf-8 (وفقا لتصريح BDFL، فإن إعداد الترميز الافتراضي في وقت التشغيل هو فكرة سيئة، لذلك في PY2، عليك خداعها بالقول import sys; reload( sys ); sys.setdefaultencoding( 'utf-8' ); ؛ أقدم حلا أفضل ل PY3K أدناه). عندما تنظر إلى إخراج هذه الخطوط الثلاثة:

b'EX\xc3\xa1MPLE'
EXáMPLE
EXÁMPLE

تستطيع أن ترى ذلك متى upper() حصلت تطبيقها على النص الأول، وهي تصرفت على البايتات، وليس على الأحرف. Python يسمح ل upper() الطريقة على البايتات، ولكن يتم تعريفها فقط على تفسير الولايات المتحدة ASCII للبايت. منذ UTF-8 يستخدم القيم داخل 8 بت ولكن الخارج من الولايات المتحدة-ASCII (128 حتى 255، والتي لا تستخدمها US-ASCII)، لن تتأثر تلك upper(), ، لذلك عندما ننفك مرة أخرى في السطر الثاني، نحصل على تلك الحالة الصغيرة á. وبعد أخيرا، الخط الثالث يفعل ذلك صحيحا، ونعم، مفاجأة، يبدو أن بيثون يدرك ذلك Á هي خطاب الحالة العليا المقابلة á. وبعد ركض اختبار سريع لمعرفة الشخصيات Python 3 لا تتحول بين العلوي والسفلي:

for cid in range( 3000 ):
  my_chr = chr( cid )
  if my_chr == my_chr.upper() and my_chr == my_chr.lower():
    say( my_chr )

تكشف الإثارة القائمة عن عدد قليل جدا من الحوادث اللاتينية أو السيريلية أو اليونانية الأحرف؛ معظم الإخراج أحرف غير أوروبية وعلامات الترقيم. الشخصيات الوحيدة التي يمكن أن أجدها أن بيثون أصبحت خاطئة هي ԥ / ԥ ( u0524، u0525، 'cyrillic {capital small} رسالة pe مع descender')، فما طالما كنت تبقى خارج كتل اللاتينية الممتدة-X ( تحقق من تلك، قد تسفر عن مفاجآت)، قد تستخدم هذه الطريقة بالفعل. بالطبع، لم أتحقق من صحة التعيينات.

أخيرا، إليك ما وضعت في قسم التمهيد تطبيق PY3K الخاص بي: طريقة تعيد تعريف الترميز sys.stdout يرى، مع مراجع الأحرف العددية (NCRS) كما تراجع؛ هذا له تأثير أن الطباعة إلى الإخراج القياسي لن يثير خطأ ترميز Unicode. عندما أعمل على أوبونتو، _sys.stdout.encoding يكون utf-8; ؛ عندما يعمل البرنامج نفسه على Windows، قد يكون الأمر شيئا جذابا مثل cp850. وبعد قد يبدو الإخراج حصصا، لكن التطبيق يعمل دون رفع استثناء في هذه المحطات الخافتة.

#===========================================================================================================
# MAKE STDOUT BEHAVE IN A FAILSAFE MANNER
#-----------------------------------------------------------------------------------------------------------
def _harden_stdout():
  """Ensure that unprintable output to STDOUT does not cause encoding errors; use XML character references
  so any kind of output gets a chance to render in a decipherable way."""
  global _sys_TRM
  _sys.stdout       = _sys_TRM = _sys_io.TextIOWrapper(
    _sys.stdout.buffer,
    encoding        = _sys.stdout.encoding,
    errors          = 'xmlcharrefreplace',
    line_buffering  = true )
#...........................................................................................................
_harden_stdout()

نصيحة واحدة أخرى: عند الاختبار، حاول دائما print repr( x ) أو شيء مشابه يكشف عن هوية x. وبعد جميع أنواع سوء الفهم يمكن أن المحاصيل إذا كنت فقط print x في PY2 و x هو إما سلسلة OMTET أو كائن Unicode. إنه محير للغاية وعرضة للتسبب في الكثير من الخدش الرأس. كما قلت، حاول التحرك على الأقل إلى PY26 مع ذلك من تعويذة حرف Unicode Unicode في المستقبل.

وإغلاق، نقلا عن Quote: "Glyph Lefkowitz يقول أنه من الأفضل في مقالته التشفير:

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

تحديث: وجدت فقط Python 3 يحول بشكل صحيح حرف S Latin Small Letter طويل S إلى S عند التحقيق. مرتب!

أعتقد أن هناك قليلا من الخلفية نحن نفتقد هنا:

>>> type('hello')
<type 'str'>

>>> type(u'hello')
<type 'unicode'>

طالما كنت تستخدم سلاسل "Unicode" بدلا من الأوتار "الأصلية"، فإن المشغلين مثل العلوي () سيعملون مع unicode في الاعتبار. Fwiw، Python 3 يستخدم Unicode افتراضيا، مما يجعل التمييز غير ذي صلة إلى حد كبير.

أخذ سلسلة من unicode ل str ثم العودة إلى unicode غير متماثل في نواح كثيرة، والعديد من المكتبات سوف تنتج إنتاج يونيكود إذا كنت تريد ذلك؛ لذلك حاول استخدام فقط unicode كائنات للأسلوت داخليا كلما استطعت.

جربها:

s = 'exámple'
print unicode(s).upper()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top