web-dev-qa-db-fra.com

Pourquoi base64.b64encode () retourne un objet bytes?

Le but de base64.b64encode() est de convertir des données binaires en "texte" ASCII-safe. Cependant, la méthode retourne un objet de type octets:

>>> import base64
>>> base64.b64encode(b'abc')
b'YWJj'

Il est facile de simplement prendre cette sortie et decode(), mais ma question est: quelle est la signification de base64.b64encode() renvoyant bytes plutôt qu'un str ?

27
gardarh

Le but de la fonction base64.b64encode () est de convertir des données binaires en "texte" ASCII-safe

Python n'est pas d'accord avec cela - base64 a été intentionnellement classé comme transformée binaire .

C'était une décision de conception en Python 3 pour forcer la séparation des octets et du texte et interdire les transformations implicites. Python est maintenant si strict à ce sujet que bytes.encode N'existe même pas, et donc b'abc'.encode('base64') lèverait un AttributeError.

L'opinion que le langage prend est qu'un objet bytestring est déjà encodé. Un codec qui code des octets en texte ne rentre pas dans ce paradigme, car lorsque vous voulez passer du domaine des octets au domaine du texte, c'est un décodage . Notez que l'encodage rot13 A également été banni de la liste des encodages standard pour la même raison - il ne cadrait pas correctement avec le paradigme Python 3 .

Il peut également y avoir un argument de performance à faire: supposez Python géré automatiquement le décodage de la sortie base64, qui est une représentation binaire codée ASCII produit par le code C du module binascii , dans un objet Python dans le domaine de texte. Si vous vouliez réellement les octets , il vous suffirait d'annuler le décodage en encodant à nouveau en ASCII. Ce serait un aller-retour inutile, une double négation inutile. Mieux vaut 'opt-in' pour le décodage- étape de texte.

20
wim

Il est impossible pour b64encode() de savoir ce que vous voulez faire avec sa sortie.

Alors que dans de nombreux cas, vous souhaiterez peut-être traiter la valeur codée comme du texte, dans de nombreux autres - par exemple, en l'envoyant sur un réseau - vous pouvez plutôt la traiter comme des octets.

Puisque b64encode() ne peut pas savoir, il refuse de deviner. Et puisque l'entrée est bytes, la sortie reste le même type, plutôt que d'être implicitement contrainte à str.

Comme vous le faites remarquer, le décodage de la sortie en str est simple:

base64.b64encode(b'abc').decode('ascii')

... et explicite sur le résultat.

En passant, il convient de noter que bien que base64.b64decode() (note: decode, pas en code) a accepté str depuis la version 3.3, le changement était quelque peu controversé .

17
Zero Piraeus