Mis a jour le 2025-04-14, 12:10

Unicode / Encodage

Unicode et encoding :
  • unicode : chaque caractère est codé par un codepoint représenté par un nombre hexadécimal, par exemple U+00E8
  • encoding : convertit l'unicode logique en stockage physique sur des octets, avec différentes solutions. Un de ces codages est UTF-8 (le plus standard et utilisé).
  • en python3, les strings (type str) sont en unicode.
Encodage / décodage :
  • l'encodage transforme une str en bytes (représentation physique), alors que le décodage transforme les bytes en str.
  • str peut être encodée en bytes en utilisant encode() :
    • myBytes = myString.encode('utf-8') pour encoder la chaîne en UTF-8 (ou myBytes = myString.encode() car utf-8 est le défaut).
    • on peut faire aussi : myBytes = bytes(myString, 'utf-8')
    • myBytes = myString.encode('iso-8859-1') : pour encoder la chaîne en ISO-8859-1.
  • myString.encode('ascii') : pour convertir en ascii, sans ignorer les erreurs : si caractère non ascii, levée d'exception UnicodeError.
  • myString.encode('ascii', errors = 'ignore') : en ignorant les erreurs (les caractères sont supprimés).
  • myString.encode('ascii', errors = 'replace') : en ignorant les erreurs (les caractères sont remplacés par des ?).
  • on peut aussi remplacer les caractères accentués par leur caractère non accentué avec le package unidecode : unidecode.unidecode(myString)
  • bytes peut être décodée en str en utilisant decode()
  • dans les 2 cas, le défaut est UTF-8, mais on peut donner aussi un autre codage.
  • récupération des bytes à partir la string : x = '\u03b2'; print(x.encode()) donne b'\xce\xb2'
  • récupération de la chaîne de caractère à partir des bytes : y = b'\xce\xb2'; print(y.decode()) donne le caractère "beta"
  • récupération du codepoint unicode : si on a un caractère et qu'on veut récupérer son codepoint : y = b'\xce\xb2'.decode().encode('unicode_escape') donne b'\u03b2'. On peut aussi faire hex(ord(b'\xce\xb2'.decode())) qui donne '0x3b2'
Pour remplacer des caractères accentués par leur équivalent html entities : s2 = s.encode('ascii', 'xmlcharrefreplace')
Pour avoir des caractères accentués dans des chaînes dans le code :
  • soit on les met en unicode : s = u'avec accents : \xe0 et \xe9'. On peut aussi utiliser à la place de \xe0 \u00e0 (indispensable si l'unicode est sur plus d'un octet). Pour avoir l'unicode d'un caractère, il suffit de lire ce caractère (en unicode) et faire dessus un repr().
  • soit on les met directement avec un certain charset, par exemple iso-8859-1 (latin-1) :
    • mettre en première ou deuxième ligne du fichier : # -*- coding: latin-1 -*-
    • puis faire directement s = u'avec accents : à et é' (ce qui est plus explicite).
Pour détecter le charset d'un bytes :
  • utiliser le package chardet : import chardet
  • chardet.detect(myBytes) : renvoie un dictionnaire ayant le format suivant : {'encoding': 'utf-8', 'confidence': 0.7525, 'language': ''}
  • donc, faire chardet.detect(myBytes)['encoding'] pour avoir l'encodage le plus probable.
Pour écrire ou lire de l'UTF-8 dans un fichier :
  • utiliser le module codecs : import codecs
  • puis, on peut alors faire :
    s = u'avec accents : \u00e0 et \u00e9'
    with codecs.open('myFile', 'w', encoding = 'utf-8') as fh:
        fh.write(s)
        
os.listdir() et accents :
  • os.listdir('/myDir1/myDir2') : renvoie les fichiers sous forme de string. C'est ok si pas d'accents ...
  • os.listdir(u'/myDir1/myDir2') ou os.listdir(unicode('/myDir1/myDir2')): renvoie les fichiers sous forme d'unicode, à utiliser si les noms de fichiers peuvent avoir des accents.
Pour convertir une chaîne de caractères avec des caractères accentués en chaîne sans accents :
  • unicodedata.normalize('NFKD', 'eéôàa').encode('ascii', 'ignore').decode() : ignore les caractère spéciaux qui ne peuvent pas être traduits et fournit en retour une chaîne ASCII (ici eeoaa).
  • dans la fonction decode() à la fin, on a une chaîne de bytes.
Codage en base64 :
  • faire import base64
  • décodage d'une chaîne encodée en base 64 : myBytes = base64.b64decode(myString) : renvoie un chaîne de bytes qu'il faut ensuite décoder selon le charset.
  • base64.b64encode('myUser:myPassword'.encode()).decode() : encodage en base64.

Copyright python-simple.com
programmer en python, tutoriel python, graphes en python, Aymeric Duclert