web-dev-qa-db-fra.com

Comment convertir des octets et des chaînes dans Python 3?

Ceci est une question de type Python 101, mais cela m’a laissé perplexe pendant un moment lorsque j’ai essayé d’utiliser un paquet qui semblait convertir mon entrée de chaîne en octets. 

Comme vous le verrez ci-dessous, j'ai trouvé la réponse moi-même, mais j'estimais que cela valait la peine d'enregistrer ici à cause du temps qu'il m'a fallu pour découvrir ce qui se passait. Il semble être générique pour Python 3, donc je n’ai pas fait référence au paquetage original avec lequel je jouais; cela ne semble pas être une erreur (simplement que le paquet en question avait une méthode .tostring() qui était clairement pas produisant ce que j'avais compris comme une chaîne ...)

Mon programme de test va comme ceci:

import mangler                                 # spoof package

stringThing = """
<Doc>
    <Greeting>Hello World</Greeting>
    <Greeting>你好</Greeting>
</Doc>
"""

# print out the input
print('This is the string input:')
print(stringThing)

# now make the string into bytes
bytesThing = mangler.tostring(stringThing)    # pseudo-code again

# now print it out
print('\nThis is the bytes output:')
print(bytesThing)

La sortie de ce code donne ceci:

This is the string input:

<Doc>
    <Greeting>Hello World</Greeting>
    <Greeting>你好</Greeting>
</Doc>


This is the bytes output:
b'\n<Doc>\n    <Greeting>Hello World</Greeting>\n    <Greeting>\xe4\xbd\xa0\xe5\xa5\xbd</Greeting>\n</Doc>\n'

Il est donc nécessaire de pouvoir convertir entre octets et chaînes pour éviter de transformer des caractères non ascii en gobbledegook.

66
Bobble

Le 'mangler' dans l'exemple de code ci-dessus faisait l'équivalent de ceci:

bytesThing = stringThing.encode(encoding='UTF-8')

Il existe d'autres moyens d'écrire cela (en utilisant notamment bytes(stringThing, encoding='UTF-8'), mais la syntaxe ci-dessus indique clairement ce qui se passe et comment procéder pour récupérer la chaîne:

newStringThing = bytesThing.decode(encoding='UTF-8')

Lorsque nous faisons cela, la chaîne d'origine est récupérée.

Notez que l’utilisation de str(bytesThing) transcrit tout le contenu de gobbledegook sans le reconvertir en Unicode, sauf si vous demandez spécifiquement UTF-8, à savoir, str(bytesThing, encoding='UTF-8'). Aucune erreur n'est signalée si le codage n'est pas spécifié.

99
Bobble

Dans python3, il existe une méthode bytes() qui a le même format que encode().

str1 = b'hello world'
str2 = bytes("hello world", encoding="UTF-8")
print(str1 == str2) # Returns True

Je n'ai rien lu à ce sujet dans la documentation, mais peut-être que je ne cherchais pas au bon endroit. De cette façon, vous pouvez explicitement transformer des chaînes en flux d'octets et les rendre plus lisibles que d'utiliser encode et decode, sans avoir à préfexer b devant des guillemets.

13
NuclearPeon

Ceci est une question de type Python 101,

C'est une question simple mais à laquelle la réponse n'est pas si simple.


En python3, un objet "octets" représente une séquence d'octets, un objet "chaîne" représente une séquence de points de code Unicode.

Pour convertir entre "octets" en "chaîne" et entre "chaîne" et "octets", vous utilisez les fonctions bytes.encode et string.decode. Ces fonctions prennent deux paramètres, un codage et une politique de gestion des erreurs.

Malheureusement, il existe énormément de cas où des séquences d'octets sont utilisées pour représenter du texte, mais le codage utilisé n'est pas nécessairement bien défini.

Si vous voulez écrire un logiciel robuste, vous devez réfléchir attentivement à ces paramètres. Vous devez bien réfléchir à l'encodage des octets et à la manière dont vous allez gérer le cas où ils s'avèrent ne pas être une séquence d'octets valide pour l'encodage auquel vous pensiez qu'ils devraient appartenir. Python utilise par défaut UTF-8. et erreur sur toute séquence d'octets qui n'est pas valide UTF-8.

print (bytesThing)

Python utilise "repr" comme conversion de secours en chaîne. repr tente de produire du code python qui recréera l’objet. Dans le cas d'un objet octets, cela signifie notamment que des octets sont échappés en dehors de la plage imprimable ascii.

0
plugwash