L’encoding en python

Avec python l’encoding est un vrai enjeux.

on a souvent l’erreur

UnicodeDecodeError: 'machine' codec can't decode
character 'trucmuche' in position x: ordinal not in range(z)

Le principe est de toujours travailler en unicode et utiliser l’encoding utf-8

En effet python ne ‘print’ correctement que du unicode

# -*- coding: utf8 -*-
a = "le père noël"
print a
print a.decode('utf-8')
a = u"le père noël"
print a

on obtient

C:\Users\fraoustin\Desktop>python test.py
le père noël
le père noël
le père noël

on peut remarquer que l’utilisation de l’unicode règle tout les problèmes

donc on a 2 grandes fonctions:

  • decode: permet le passage d’un encoding vers l’unicode
  • encode: permet le passage de l’unicode vers l’encoding

l’encode peut être utiliser pour envoyer des str vers un système externe comme les mails, un sgbd, ...

voilà un exemple concret: dans une application web nous récupérons des données avec l’encoding utf-8 que nous souhaitons intégrer dans une base en is-8859-15 ... notre code devient

recup_data = request.get('name')
save_data(recup_data.decode('utf-8').encode('iso-8859-15'))

Il est possible dans le cas de connexion avec des bases de données d’avoir les résultats sous format unicode directement

cnxn = pyodbc.connect('DSN=test;PWD=password', unicode_results=True)
cdata = cnxn.cursor()
cdata.execute("select user_id, user_name from users")
for i in cdata.fetchall():
    print i[0], i[1] #la on imprime des unicodes

en python3 tout les string sont en unicode et la fonction unicode n’existe plus

Pour qu’un code python2 utilisant python3 soit compatible il faut ajouter le code suivant

import platform
if int(platform.python_version_tuple()[0]) > 2:
    def unicode(a):
        return str(a)

Dans un terminal il est assez simple de connaitre les caractères qui peuvent être “printer”

for i in range(1,128):
    print "%3s : %s" % (i, unichr(i))