La meilleure façon de convertir une chaîne en octets en Python 3?

il semble y avoir deux façons différentes de convertir une chaîne en octets, comme le montrent les réponses à TypeError: "str" ne supporte pas l'interface de tampon

laquelle de ces méthodes serait meilleure ou plus pythonique? Ou est-ce juste une question de préférence personnelle?

b = bytes(mystring, 'utf-8')

b = mystring.encode('utf-8')
461
demandé sur Community 2011-09-28 19:14:07

5 réponses

si vous regardez le docs pour bytes , il vous indique à bytearray :

bytearray([source[, encodage [erreurs]]])

renvoie un nouveau tableau d'octets. Le type bytearray est une séquence mutable d'entiers dans l'intervalle 0 <= x < 256. Il a la plupart des méthodes habituelles de séquences mutables, décrites dans les types de séquences mutables, ainsi que la plupart des méthodes que le type d'octets a, voir octets et les méthodes de Tableau de Byte.

le paramètre Source optionnel peut être utilisé pour initialiser le tableau de différentes façons:

S'il s'agit d'une chaîne, vous devez également donner les paramètres d'encodage (et éventuellement, les erreurs); bytearray() convertit alors la chaîne en octets en utilisant str.encodage.)(

si c'est un entier, le tableau aura cette taille et sera initialisé avec null octet.

S'il s'agit d'un objet conforme à l'interface buffer, un tampon en lecture seule de l'objet sera utilisé pour initialiser le tableau d'octets.

S'il s'agit d'un itérable, il doit s'agir d'un itérable de nombres entiers dans l'intervalle 0 <= x < 256, qui sont utilisés comme contenu initial du tableau.

sans argument, un tableau de taille 0 est créé.

donc bytes peut faire beaucoup plus que simplement encoder une chaîne. C'est Pythonic qu'il vous permet d'appeler le constructeur avec n'importe quel type de paramètre source qui fait sens.

pour encoder une chaîne, je pense que some_string.encode(encoding) est plus pythonique qu'utiliser le constructeur, parce que c'est le plus auto-documentant -- "prendre cette chaîne et l'encoder avec cet encodage" est plus clair que bytes(some_string, encoding) -- il n'est pas explicite verbe lorsque vous utilisez le constructeur.

Edit: j'ai vérifié la source de Python. Si vous passez une chaîne unicode à bytes en utilisant CPython, elle appelle PyUnicode_AsEncodedString , qui est la mise en œuvre de encode ; donc vous sautez juste un niveau d'indirecte si vous appelez vous-même encode .

aussi, voir le commentaire de Serdalis -- unicode_string.encode(encoding) est aussi plus pythonique parce que son inverse est byte_string.decode(encoding) et la symétrie est agréable.

376
répondu agf 2017-10-04 04:42:58

Son plus facile que l'on pense:

my_str = "hello world"
my_str_as_bytes = str.encode(my_str)
type(my_str_as_bytes) # ensure it is byte representation
my_decoded_str = my_str_as_bytes.decode()
type(my_decoded_str) # ensure it is string representation
164
répondu hasanatkazmi 2017-03-17 13:44:12

Le absolument la meilleure manière qui n'est ni de la 2, mais le 3. Le premier paramètre à encode par défaut, 'utf-8' depuis Python 3.0. Ainsi le meilleur moyen est

b = mystring.encode()

ce sera aussi plus rapide, parce que l'argument par défaut résulte non pas dans la chaîne "utf-8" dans le code C, mais NULL , qui est beaucoup plus rapide à vérifier!

Ici il y a quelques timings:

In [1]: %timeit -r 10 'abc'.encode('utf-8')
The slowest run took 38.07 times longer than the fastest. 
This could mean that an intermediate result is being cached.
10000000 loops, best of 10: 183 ns per loop

In [2]: %timeit -r 10 'abc'.encode()
The slowest run took 27.34 times longer than the fastest. 
This could mean that an intermediate result is being cached.
10000000 loops, best of 10: 137 ns per loop

malgré l'avertissement, les temps étaient très stables après des descentes répétées - l'écart n'était que de ~2 pour cent.


utiliser encode() sans argument N'est pas compatible avec Python 2, car dans Python 2 le codage de caractères par défaut est ASCII .

>>> 'äöä'.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)
42
répondu Antti Haapala 2018-06-23 07:21:40

vous pouvez simplement convertir la chaîne en octets en utilisant:

a_string.encode()

et vous pouvez simplement convertir des octets en chaîne en utilisant:

some_bytes.decode()

bytes.decode et str.encode ont encoding='utf-8' comme valeur par défaut.

les fonctions suivantes (tirées de Effective Python ) pourraient être utiles pour convertir str en bytes et bytes à str :

def to_bytes(bytes_or_str):
    if isinstance(bytes_or_str, str):
        value = bytes_or_str.encode() # uses 'utf-8' for encoding
    else:
        value = bytes_or_str
    return value # Instance of bytes


def to_str(bytes_or_str):
    if isinstance(bytes_or_str, bytes):
        value = bytes_or_str.decode() # uses 'utf-8' for encoding
    else:
        value = bytes_or_str
    return value # Instance of str
29
répondu lmiguelvargasf 2017-09-26 11:18:19
so_string = 'stackoverflow'
so_bytes = so_string.encode( )
8
répondu gerardw 2017-06-16 19:09:32