Quelle est la différence entre encoder/décoder?

Je n'ai jamais été sûr de comprendre la différence entre str/unicode Décoder et encoder.

je sais que str().decode() est pour quand vous avez une chaîne d'octets que vous savez avoir un certain encodage de caractères, étant donné que le nom d'encodage il retournera une chaîne unicode.

je sais que unicode().encode() convertit les caractères unicode en une chaîne d'octets selon un nom d'encodage.

mais je ne comprends pas str().encode() et unicode().decode() sont pour. Est-ce que quelqu'un peut expliquer, et peut-être aussi corriger quelque chose que je me suis trompé ci-dessus?

EDIT:

plusieurs réponses donnent des informations sur ce que .encode fait sur une chaîne, mais personne ne semble savoir ce que .decode fait pour unicode.

161
demandé sur cedbeu 2009-01-15 18:13:59

7 réponses

la méthode decode des chaînes unicode n'a vraiment aucune application (à moins que vous ayez des données non textuelles dans une chaîne unicode pour une raison quelconque -- voir ci-dessous). C'est essentiellement pour des raisons historiques, je pense. En Python 3, il a complètement disparu.

unicode().decode() exécutera un codant de s en utilisant le codec par défaut (ascii).

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

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

Les messages d'erreur sont exactement les mêmes.

pour str().encode() c'est l'inverse -- il tente un décodage implicite de s avec l'encodage par défaut:

>>> s = 'ö'
>>> s.decode('utf-8')
u'\xf6'
>>> s.encode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
ordinal not in range(128)

utilisé comme ceci, str().encode() est également superflu.

mais il y a une autre application de cette dernière méthode qui est utile: il y a codages qui n'ont rien à voir avec les jeux de caractères, et peuvent donc être appliquées à des chaînes 8 bits d'une manière significative:

>>> s.encode('zip')
'x\x9c;\xbc\r\x00\x02>\x01z'

Vous avez raison, cependant: l'ambiguïté de l'utilisation de "l'encodage" pour ces deux applications est... awkard. Encore une fois, avec les types séparés byte et string en Python 3, ce n'est plus un problème.

96
répondu 2013-11-07 17:53:24

Pour représenter une chaîne unicode comme une chaîne d'octets est connu comme encodage . Utilisez u'...'.encode(encoding) .

exemple:

    >>> u'æøå'.encode('utf8')
    '\xc3\x83\xc2\xa6\xc3\x83\xc2\xb8\xc3\x83\xc2\xa5'
    >>> u'æøå'.encode('latin1')
    '\xc3\xa6\xc3\xb8\xc3\xa5'
    >>> u'æøå'.encode('ascii')
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: 
    ordinal not in range(128)

vous encodez typiquement une chaîne unicode chaque fois que vous avez besoin de L'utiliser pour IO, par exemple le transférer sur le réseau, ou le sauvegarder dans un fichier disque.

pour convertir une chaîne d'octets en chaîne unicode est connu comme décodage . Utiliser unicode('...', encoding) ou '...'.décoder(encodage).

exemple:

   >>> u'æøå'
   u'\xc3\xa6\xc3\xb8\xc3\xa5' # the interpreter prints the unicode object like so
   >>> unicode('\xc3\xa6\xc3\xb8\xc3\xa5', 'latin1')
   u'\xc3\xa6\xc3\xb8\xc3\xa5'
   >>> '\xc3\xa6\xc3\xb8\xc3\xa5'.decode('latin1')
   u'\xc3\xa6\xc3\xb8\xc3\xa5'

vous décodez typiquement une chaîne d'octets chaque fois que vous recevez des données de chaîne du réseau ou d'un dossier de disque.

je crois qu'il y a quelques changements dans la manipulation d'unicode en python 3, donc ce qui précède n'est probablement pas correct pour python 3.

Quelques bons liens:

62
répondu codeape 2012-07-23 07:39:52

anUnicode. encoder ('encoding') donne un string objet et peut être appelé sur un objet unicode

aString. decode ('encoding') donne un objet unicode et peut être appelé sur une chaîne, encodée dans un encodage donné.


quelques explications supplémentaires:

vous pouvez créer un objet unicode, qui n'ont pas de codage de jeu. La façon dont il est stocké par Python en mémoire ne vous concerne pas. Vous pouvez le chercher, le diviser et appeler n'importe quelle fonction de manipulation de chaîne que vous aimez.

mais il vient un moment, où vous souhaitez imprimer votre objet unicode à la console ou dans un fichier texte. Donc vous devez encoder it (par exemple - en UTF-8), vous appelez encoder('utf-8') et vous obtenez une chaîne de caractères Avec '\u' à l'intérieur, qui est parfaitement imprimable.

puis, encore une fois-vous aimeriez faire la chaîne de caractères codée en UTF-8 et la traiter comme un Unicode, de sorte que le \u360 serait un caractère, pas 5. Ensuite ,vous décoder une chaîne de caractères (avec encodage sélectionné) et obtenir tout nouvel objet du type unicode.

tout comme une note latérale - vous pouvez sélectionner certains encodage pervers, comme "zip", "base64", "rot" et certains d'entre eux se convertiront de chaîne en chaîne, mais je crois le cas le plus commun est celui qui implique UTF-8 / UTF-16 et string.

13
répondu Abgan 2009-01-16 23:11:40

mybytestring.encode (somecodec) est significatif pour ces valeurs de somecodec :

  • base64
  • bz2
  • zlib
  • hex
  • quopri
  • rot13
  • string_escape
  • uu

Je ne suis pas sûr de savoir à quoi sert le décodage d'un texte unicode déjà décodé. En essayant qu'avec tout encodage semble toujours essayer de coder avec l'encodage par défaut du système en premier.

12
répondu nosklo 2009-01-15 16:15:39

Vous devriez lire Python UnicodeDecodeError - Suis-je malentendu coder . Ma compréhension d'unicode en Python était beaucoup plus claire après avoir lu la réponse acceptée.

8
répondu Oli 2017-05-23 12:03:06

il y a quelques encodages qui peuvent être utilisés pour décoder de str à str ou d'unicode à unicode. Par exemple base64, hex ou même rot13. Ils sont répertoriés dans le module codecs .

Edit:

le message de décodage sur une chaîne unicode peut annuler l'opération d'encodage correspondante:

In [1]: u'0a'.decode('hex')
Out[1]: '\n'

le type retourné est str au lieu d'unicode ce qui est malheureux à mon avis. Mais quand vous ne font pas un en-/décoder correctement entre str et unicode cela ressemble à un gâchis de toute façon.

5
répondu 2009-01-15 19:13:01

la réponse simple est qu'ils sont exactement le contraire l'un de l'autre.

l'ordinateur utilise l'Unité de base de byte pour stocker et traiter l'information, il est dénué de sens pour les yeux humains.

par exemple, "\xe4\xb8\xad\xe6\x96\x87" est la représentation de deux caractères chinois, mais l'ordinateur sait seulement (ce qui signifie imprimer ou stocker) ce sont les caractères chinois quand ils sont donnés un dictionnaire pour chercher ce mot chinois, dans ce cas, il est" utf-8 " dictionnaire, et il ne serait pas correctement montrer le mot chinois prévu si vous regardez dans un dictionnaire différent ou mauvais(en utilisant une méthode de décodage différente).

dans le cas ci-dessus, le processus par lequel un ordinateur cherche un mot chinois est le décodage().

Et le processus de l'ordinateur à écrire le Chinois dans la mémoire de l'ordinateur est encode ().

ainsi l'information d'encodage est les octets bruts, et l'information décodée est les octets brutes et le nom du dictionnaire de référence (mais pas le dictionnaire lui-même).

0
répondu Eren Bay 2018-08-03 18:32:06