web-dev-qa-db-fra.com

chaîne d'octets vs chaîne unicode. Python

Pourriez-vous expliquer en détail la différence entre la chaîne d'octets et la chaîne Unicode en Python. J'ai lu this :

Le code d'octet est simplement le code source converti en tableaux d'octets

Cela signifie-t-il que Python a son propre format de codage/codage? Ou utilise-t-il les paramètres du système d'exploitation? Je ne comprends pas. Pourriez-vous s'il vous plaît expliquer? Merci!

37
ashim

Non python n'utilise pas son propre encodage. Il utilisera tous les encodages auxquels il a accès et que vous spécifiez. Un caractère dans un str représente un caractère unicode. Cependant pour représentent plus de 256 caractères, les codages Unicode individuels utilisent plus d'un octet par caractère pour représenter plusieurs caractères. Les objets bytearray vous donnent accès aux octets sous-jacents. Les objets str ont le encode méthode qui prend une chaîne représentant un encodage et renvoie l'objet bytearray qui représente la chaîne dans cet encodage. Les objets bytearray ont la méthode decode qui prend une chaîne représentant un encodage et renvoie le str résultant de l'interprétation du bytearray comme une chaîne codée dans le codage donné. Voici un exemple.

>>> a = "αά".encode('utf-8')
>>> a
b'\xce\xb1\xce\xac'
>>> a.decode('utf-8')
'αά'

Nous pouvons voir que UTF-8 utilise quatre octets,\xce,\xb1,\xce et\xac pour représenter deux caractères. Après l'article Spolsky auquel Ignacio Vazquez-Abrams a fait référence, je lirais le Python Unicode Howto .

36
aaronasterling

Voici une tentative d'explication simple qui ne s'applique qu'à Python 3. J'espère que venant d'un profane, cela aiderait à dissiper une certaine confusion pour les non initiés. S'il y a des inexactitudes techniques , veuillez me pardonner et n'hésitez pas à le signaler.

Supposons que vous créez une chaîne en utilisant Python 3 de la manière habituelle:

stringobject = 'ant'

stringobject serait une chaîne unicode.

Une chaîne unicode est composée de caractères unicode. Dans stringobject ci-dessus, les caractères unicode sont les lettres individuelles, par ex. a, n, t

Chaque caractère unicode se voit attribuer un point de code, qui peut être exprimé sous la forme d'une séquence de chiffres hexadécimaux (un chiffre hexadécimal peut prendre 16 valeurs, allant de 0 à 9 et A à F). Par exemple, la lettre 'a' est équivalent à '\u0061', et 'ant' équivaut à '\u0061\u006E\u0074'.

Vous constaterez donc que si vous tapez,

stringobject = '\u0061\u006E\u0074'
stringobject

Vous obtiendrez également la sortie 'ant'.

Maintenant, nicode est converti en octets, dans un processus connu sous le nom de encoding. Le processus inverse de conversion d'octets en unicode est appelé décodage.

Comment cela se fait-il? Étant donné que chaque chiffre hexadécimal peut prendre 16 valeurs différentes, il peut être reflété dans une séquence binaire de 4 bits (par exemple, le chiffre hexadécimal 0 peut être exprimé en binaire comme 0000, le chiffre hexadécimal 1 peut être exprimé comme 0001 et ainsi de suite). Si un caractère unicode a un point de code composé de quatre chiffres hexadécimaux, il aurait besoin d'une séquence binaire de 16 bits pour le coder.

Différents systèmes de codage spécifient des règles différentes pour convertir unicode en bits. Plus important encore, les codages diffèrent par le nombre de bits qu'ils utilisent pour exprimer chaque caractère unicode.

Par exemple, le système de codage ASCII n'utilise que 8 bits (1 octet) par caractère. Ainsi, il ne peut coder que des caractères unicode avec des points de code jusqu'à deux chiffres hexadécimaux (soit 256 caractères unicode différents) Le système de codage UTF-8 utilise 8 à 32 bits (1 à 4 octets) par caractère, il peut donc coder des caractères unicode avec des points de code jusqu'à 8 chiffres hexadécimaux, c'est-à-dire tout.

Exécution du code suivant:

byteobject = stringobject.encode('utf-8')
byteobject, type(byteobject)

convertit une chaîne unicode en chaîne d'octets à l'aide du système de codage utf-8 et renvoie b'ant', bytes'.

Notez que si vous avez utilisé 'ASCII' comme système de codage, vous ne rencontreriez aucun problème car tous les points de code dans 'ant' peuvent être exprimés avec 1 octet. Mais si vous aviez une chaîne unicode contenant des caractères avec des points de code supérieurs à deux chiffres hexadécimaux, vous obtiendrez un UnicodeEncodeError.

De même,

stringobject = byteobject.decode('utf-8')
stringobject, type(stringobject)

vous donne 'ant', str.

29
runawaykid