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')
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.
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
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)
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