web-dev-qa-db-fra.com

Python: Utilisation de .format () sur une chaîne échappée par Unicode

J'utilise Python 2.6.5. Mon code nécessite l'utilisation du signe "supérieur ou égal à". La voici:

>>> s = u'\u2265'
>>> print s
>>> ≥
>>> print "{0}".format(s)
Traceback (most recent call last):
     File "<input>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2265'
  in position 0: ordinal not in range(128)`  

Pourquoi ai-je cette erreur? Y a-t-il une bonne façon de faire cela? J'ai besoin d'utiliser la fonction .format().

153
Kit

Faites juste la deuxième chaîne aussi une chaîne unicode

>>> s = u'\u2265'
>>> print s
≥
>>> print "{0}".format(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2265' in position 0: ordinal not in range(128)
>>> print u"{0}".format(s)
≥
>>> 
236
Mad Scientist

unicodes a besoin de unicode chaînes de format.

>>> print u'{0}'.format(s)
≥
69

Un peu plus d'informations sur pourquoi cela se produit.

>>> s = u'\u2265'
>>> print s

fonctionne parce que print utilise automatiquement le codage système pour votre environnement, qui a probablement été défini sur UTF-8. (Vous pouvez vérifier en faisant import sys; print sys.stdout.encoding)

>>> print "{0}".format(s)

échoue car format essaie de faire correspondre l'encodage du type sur lequel il est appelé (je n'ai pas trouvé de documentation à ce sujet, mais c'est le comportement que j'ai remarqué). Comme les littéraux de chaîne sont des chaînes d'octets codées comme ASCII dans python 2, format tente de coder s en tant qu'ASCII, ce qui entraîne ensuite cette exception. Observer:

>>> s = u'\u2265'
>>> s.encode('ascii')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2265' in position 0: ordinal not in range(128)

C’est la raison pour laquelle ces approches fonctionnent:

>>> s = u'\u2265'
>>> print u'{}'.format(s)
≥
>>> print '{}'.format(s.encode('utf-8'))
≥

Le jeu de caractères source est défini par la déclaration de codage; c'est ASCII si aucune déclaration d'encodage n'est donnée dans le fichier source ( https://docs.python.org/2/reference/lexical_analysis.html#string-literals )

2
lps