Apparemment, ce qui suit est une syntaxe valide
my_string = b'The string'
J'aimerais savoir:
b
devant la chaîne?J'ai trouvé un question connexe ici même sur SO, mais cette question concerne PHP cependant, et indique que la b
est utilisée pour indiquer que la chaîne est binaire, contrairement à Unicode, qui était nécessaire pour que le code soit compatible à partir de la version de PHP <6, lors de la migration vers PHP 6. Je ne pense pas que cela s'applique à Python.
J'ai trouvé cette documentation sur le site Python concernant l'utilisation d'un caractère u
dans la même syntaxe pour spécifier une chaîne au format Unicode. Malheureusement, le caractère b ne figure nulle part dans ce document.
Aussi, juste par curiosité, y a-t-il plus de symboles que les b
et u
qui font autre chose?
Pour citer la documentation Python 2.x :
Un préfixe 'b' ou 'B' est ignoré dans Python 2; il indique que le littéral doit devenir un littéral d'octets dans Python 3 (par exemple, lorsque le code est automatiquement converti avec 2to3). Un préfixe "u" ou "b" peut être suivi d'un préfixe "r".
Le documentation Python indique:
Les littéraux d'octets sont toujours précédés de 'b' ou 'B'; ils produisent une instance du type octets au lieu du type str. Ils ne peuvent contenir que ASCII caractères; les octets avec une valeur numérique de 128 ou plus doivent être exprimés avec des échappements.
Python 3.x distingue clairement les types:
str
= '...'
littéraux = une séquence de caractères Unicode (UTF-16 ou UTF-32, selon la manière dont Python a été compilé)bytes
= b'...'
littéraux = une séquence d'octets (entiers compris entre 0 et 255)Si vous connaissez Java ou C #, considérez str
comme String
et bytes
comme byte[]
. Si vous connaissez SQL, considérez str
comme NVARCHAR
et bytes
comme BINARY
ou BLOB
. Si vous connaissez le registre Windows, imaginez str
comme REG_SZ
et bytes
comme REG_BINARY
. Si vous connaissez C (++), oubliez tout ce que vous avez appris sur char
et les chaînes, car UN CARACTÈRE IS PAS UN BYTE . Cette idée est obsolète depuis longtemps.
Vous utilisez str
lorsque vous souhaitez représenter du texte.
print('שלום עולם')
Vous utilisez bytes
lorsque vous souhaitez représenter des données binaires de bas niveau, telles que des structures.
NaN = struct.unpack('>d', b'\xff\xf8\x00\x00\x00\x00\x00\x00')[0]
Vous pouvez encoder un str
en un objet bytes
.
>>> '\uFEFF'.encode('UTF-8')
b'\xef\xbb\xbf'
Et vous pouvez décoder une bytes
en str
.
>>> b'\xE2\x82\xAC'.decode('UTF-8')
'€'
Mais vous ne pouvez pas mélanger librement les deux types.
>>> b'\xEF\xBB\xBF' + 'Text with a UTF-8 BOM'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't concat bytes to str
La notation b'...'
est quelque peu déroutante dans la mesure où elle permet de spécifier les octets 0x01-0x7F avec des caractères ASCII au lieu de nombres hexadécimaux.
>>> b'A' == b'\x41'
True
Mais je dois souligner, qu'un caractère n'est pas un octet .
>>> 'A' == b'A'
False
Les versions antérieures à la version 3.0 de Python ne présentaient pas ce type de distinction entre le texte et les données binaires. Au lieu de cela, il y avait:
unicode
= u'...'
littéraux = séquence de caractères Unicode = 3.x str
str
= '...'
littéraux = séquences d'octets/caractères confondus struct.pack
output.Afin de faciliter la transition de 2.x à 3.x, la syntaxe littérale b'...'
a été reportée sur Python 2.6, afin de permettre la distinction des chaînes binaires (qui devrait être bytes
dans 3.x) à partir de chaînes de texte (qui devrait être str
dans 3.x). Le préfixe b
ne fait rien dans la version 2.x, mais indique au script 2to3
de ne pas le convertir en chaîne Unicode en 3.x.
Alors oui, b'...'
les littéraux de Python ont le même objectif que ceux de PHP.
Aussi, juste par curiosité, y a-t-il plus de symboles que le b et u qui font autre chose?
Le préfixe r
crée une chaîne brute (par exemple, r'\t'
est une barre oblique inverse + t
au lieu d'un onglet), et des guillemets triples '''...'''
ou """..."""
permettent plusieurs -lignes de chaînes de caractères.
Le b indique une chaîne d'octets.
Les octets sont les données réelles. Les chaînes sont une abstraction.
Si vous aviez un objet chaîne à plusieurs caractères et que vous preniez un seul caractère, il s'agirait d'une chaîne, dont la taille pourrait être supérieure à 1 octet, en fonction de l'encodage.
Si vous prenez 1 octet avec une chaîne d'octets, vous obtiendrez une valeur unique de 8 bits comprise entre 0 et 255 et il se peut que ce dernier ne représente pas un caractère complet si ces caractères dus au codage étaient supérieurs à 1 octet.
TBH J'utilisais des chaînes sauf si j'avais une raison particulière d'utiliser des octets.
Du côté du serveur, si nous envoyons une réponse, elle sera envoyée sous la forme de type octet, elle apparaîtra donc dans le client sous la forme b'Response from server'
Pour vous débarrasser de b'....'
, utilisez simplement le code ci-dessous:
Fichier serveur:
stri="Response from server"
c.send(stri.encode())
Dossier client:
print(s.recv(1024).decode())
alors il imprimera Response from server
Il le transforme en un littéral bytes
(ou str
dans 2.x) et est valide à partir de la version 2.6.
Le préfixe r
fait en sorte que les barres obliques inverses soient "non interprétées" (pas ignorées, et la différence fait importe).
Voici un exemple où l'absence de b
lève une exception TypeError
dans Python 3.x
>>> f=open("new", "wb")
>>> f.write("Hello Python!")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' does not support the buffer interface
Ajouter un préfixe b
résoudrait le problème.
Outre ce que d'autres ont dit, notez qu'un seul caractère en unicode peut être composé de plusieurs octets .
Le fonctionnement de l’unicode est qu’il reprenait l’ancien format ASCII (code 7 bits ressemblant à 0xxx xxxx) et ajoutait séquences multi-octets où tous les octets commencent par 1 (1xxx). xxxx) pour représenter des caractères au-delà de ASCII afin que Unicode soit rétrocompatible avec ASCII.
>>> len('Öl') # German Word for 'oil' with 2 characters
2
>>> 'Öl'.encode('UTF-8') # convert str to bytes
b'\xc3\x96l'
>>> len('Öl'.encode('UTF-8')) # 3 bytes encode 2 characters !
3
Vous pouvez utiliser JSON pour le convertir en dictionnaire
import json
data = b'{"key":"value"}'
print(json.loads(data))
{"valeur clé"}
BALLON:
Ceci est un exemple de flask. Exécutez ceci sur la ligne de terminal:
import requests
requests.post(url='http://localhost(example)/',json={'key':'value'})
En fiole/routes.py
@app.route('/', methods=['POST'])
def api_script_add():
print(request.data) # --> b'{"hi":"Hello"}'
print(json.loads(request.data))
return json.loads(request.data)
{'valeur clé'}