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 prend pas en charge l'interface de tampon
Laquelle de ces méthodes serait meilleure ou plus Pythonique? Ou s'agit-il simplement d'une préférence personnelle?
b = bytes(mystring, 'utf-8')
b = mystring.encode('utf-8')
python
string
character-encoding
python-3.x
Mark Ransom
la source
la source
bytes(item, "utf8")
, car explicite vaut mieux qu'implicite, donc ... parstr.encode( )
défaut en octets, ce qui vous rend plus Unicode-zen mais moins Explicit-Zen. "Commun" n'est pas non plus un terme que j'aime suivre. En outrebytes(item, "utf8")
,, ressemble davantage àstr()
, et auxb"string"
notations. Mes excuses si je suis tellement noob pour comprendre vos raisons. Je vous remercie.encode()
cela n'appelle pasbytes()
, c'est l'inverse. Bien sûr, ce n'est pas immédiatement évident, c'est pourquoi j'ai posé la question.Réponses:
Si vous regardez les documents
bytes
, cela vous indiquebytearray
:bytes
Peut donc faire bien plus que simplement coder une chaîne. C'est Pythonic qu'il vous permettrait d'appeler le constructeur avec n'importe quel type de paramètre source qui a du sens.Pour encoder une chaîne, je pense que
some_string.encode(encoding)
c'est plus Pythonic que d'utiliser le constructeur, parce que c'est la plus auto-documentée - "prenez cette chaîne et encodez-la avec cet encodage" est plus clair quebytes(some_string, encoding)
- il n'y a pas de verbe explicite lorsque vous utilisez le constructeur.Edit: j'ai vérifié la source Python. Si vous passez une chaîne unicode à l'
bytes
utilisation de CPython, il appelle PyUnicode_AsEncodedString , qui est l'implémentation deencode
; donc vous sautez juste un niveau d'indirection si vous vous appelezencode
.Voir aussi le commentaire de Serdalis -
unicode_string.encode(encoding)
est également plus Pythonic car son inverse estbyte_string.decode(encoding)
et la symétrie est agréable.la source
unicode_string.encode(encoding)
parfaitementbytearray.decode(encoding)
lorsque vous souhaitez récupérer votre chaîne.bytearray
est utilisé lorsque vous avez besoin d'un objet modifiable. Vous n'avez pas besoin pour de simplesstr
↔bytes
conversions.bytearray
que les documents pourbytes
ne donnent pas de détails, ils disent simplement "ceci est une version immuable debytearray
" donc je dois citer à partir de là.bytes
: Évitez d'utiliser le type d'octets en tant que fonction avec un argument entier. Dans la v2, cela renvoie l'entier converti en une chaîne (octet) car les octets sont un alias pour str, tandis que dans la v3, il renvoie une chaîne d'octets contenant le nombre donné de caractères nuls. Ainsi, par exemple, au lieu des octets d'expression v3 (6), utilisez l'équivalent b '\ x00' * 6, qui fonctionne de manière transparente de la même manière dans chaque version.byte_string.decode('latin-1')
asutf-8
ne couvre pas toute la plage 0x00 à 0xFF (0-255), consultez les documents python pour Plus d'informations.C'est plus facile qu'on ne le pense:
la source
obj.method()
syntaxe au lieu de lacls.method(obj)
syntaxe c'est-à-dire, utilisezbytestring = unicode_text.encode(encoding)
etunicode_text = bytestring.decode(encoding)
.self
comme premier argumentencode
comme méthode liée sur la chaîne. Cette réponse suggère que vous devez à la place appeler la méthode non liée et lui passer la chaîne. C'est la seule nouvelle information dans la réponse, et c'est faux.La absolument meilleur moyen est ni de 2, mais le 3ème. Le premier paramètre par défaut depuis Python 3.0. Ainsi, la meilleure façon est
encode
'utf-8'
Ce sera également plus rapide, car l'argument par défaut n'entraîne pas la chaîne
"utf-8"
dans le code C, maisNULL
ce qui est beaucoup plus rapide à vérifier!Voici quelques horaires:
Malgré l'avertissement, les temps étaient très stables après des cycles répétés - l'écart n'était que de ~ 2%.
L'utilisation
encode()
sans argument n'est pas compatible avec Python 2, car dans Python 2 le codage de caractères par défaut est ASCII .la source
'\u00012345'*10000
. Les deux prennent 28.8us sur mon ordinateur portable; les 50 ns supplémentaires sont probablement perdues dans l'erreur d'arrondi. Bien sûr, c'est un exemple assez extrême, mais il'abc'
est tout aussi extrême dans la direction opposée.