J'utilise Python 2.6 et Jinja2 pour créer des rapports HTML. Je fournis le modèle avec de nombreux résultats et le modèle y passe en boucle et crée des tableaux HTML
En appelant template.render, j'ai soudainement commencé à avoir cette erreur.
<td>{{result.result_str}}</td>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 0: ordinal not in range(128)
La chose étrange est que, même si je mets result.result_str dans une simple chaîne ascii telle que "abc" pour chaque résultat, je vois encore cette erreur. Je suis nouveau dans les domaines Jinja2 et Python et apprécierais toutes les idées sur la manière dont je pourrais enquêter sur le problème pour en arriver à la cause fondamentale.
Si vous obtenez une erreur avec une chaîne telle que "ABC", le caractère non-ASCII est peut-être ailleurs. Peut-être dans la source du modèle?
Dans tous les cas, utilisez des chaînes Unicode dans votre application pour éviter ce genre de problème. Si votre source de données vous fournit des chaînes d'octets, vous obtenez des chaînes unicode avec byte_string.decode('utf-8')
, si la chaîne est codée en UTF-8. Si votre source est un fichier, utilisez la classe StreamReader
dans le module codecs.
Si vous n'êtes pas sûr de la différence entre les chaînes Unicode et les chaînes ordinaires, lisez ceci: http://www.joelonsoftware.com/articles/Unicode.html
Essayez d'ajouter ceci:
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
Cela a résolu mon problème, bonne chance.
De http://jinja.pocoo.org/docs/api/#unicode
Jinja2 utilise Unicode en interne, ce qui signifie que vous devez transmettre des objets Unicode à la fonction de rendu ou à des bytestrings composés uniquement de caractères ASCII.
Ainsi, chaque fois que vous définissez result.result_str, vous devez le rendre unicode, par exemple.
result.result_str = unicode(my_string_variable, "utf8")
(Si vos octets étaient au format Unicode codé en utf8)
ou
result.result_str = u"my string"
Je viens de rencontrer le même problème dans un morceau de code qui enregistre la sortie de Jinja2 dans des fichiers HTML:
with open(path, 'wb') as fh:
fh.write(template.render(...))
Il est facile de blâmer Jinja2, bien que le problème actuel se trouve dans la fonction open()
de Python qui, à compter de la version 2.7, ne prend pas en charge UTF-8. Le correctif est aussi simple que:
import codecs
with codecs.open(path, 'wb', 'utf-8') as fh:
fh.write(template.render(...))
Les chaînes simples peuvent contenir des octets de caractères UTF-8 mais elles ne sont pas de type unicode. Ceci peut être corrigé par "decode" qui convertit str en unicode. Fonctionne en Python 2.5.5.
my_string_variable.decode ("utf8")
ASCII est un code de 7 bits. La valeur 0xC4 ne peut pas être stockée sur 7 bits. Par conséquent, vous utilisez le codage incorrect pour ces données.