Que fait le caractère " b " devant une chaîne littérale?
apparemment, la syntaxe suivante est valide
my_string = b'The string'
j'aimerais savoir:
- que signifie ce caractère
b
devant la chaîne? - Quels sont les effets de l'aide?
- quelles sont les situations appropriées pour l'utiliser?
j'ai trouvé une question connexe ici-même, mais cette question Est A propos de PHP cependant, et il est dit que le b
est utilisé pour indiquer que la chaîne est binaire, par opposition à 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 à propos de l'utilisation d'un caractère u
dans la même syntaxe pour spécifier une chaîne comme Unicode. Malheureusement, il ne mentionne pas le b n'importe où dans ce document.
aussi, juste par curiosité, y a-t-il plus de symboles que b
et u
qui font autre chose?
7 réponses
pour citer le Python 2.x documentation :
Un préfixe de " b " ou " B " est ignoré dans Python 2; Il indique que le littérale devrait devenir un octets littérale en Python 3 (par exemple quand le code est conversion automatique avec 2to3). Un 'u' ou 'b' préfixe peut être suivie par un " r " préfixe.
Le Python 3.3 documentation : le
Bytes les lettres sont toujours préfixées avec' b 'ou' B'; elles produisent une instance du type bytes au lieu du type str. Ils ne peuvent contenir que des caractères ASCII; les octets ayant une valeur numérique de 128 ou plus doivent être exprimés avec des évasions.
Python 3.x fait une distinction claire entre les types:
-
str
='...'
littérales = une séquence de caractères Unicode (UTF-16 ou UTF-32, selon la façon dont Python a été compilé) -
bytes
=b'...'
littérales = une séquence d'octets (entiers entre 0 et 255)
si vous connaissez Java ou C#, pensez à str
comme String
et bytes
comme byte[]
. Si vous connaissez SQL, pensez à str
comme NVARCHAR
et bytes
comme BINARY
ou BLOB
. Si vous êtes familier avec le registre de Windows, pensez à str
comme REG_SZ
et bytes
comme REG_BINARY
. Si vous êtes familier avec C(++), alors oubliez tout ce que vous avez appris sur char
et les cordes, parce que un personnage n'est pas un octet . Cette idée est obsolète depuis longtemps.
vous utilisez str
lorsque vous voulez représenter du texte.
print('שלום עולם')
vous utilisez bytes
lorsque vous voulez représenter des données binaires de bas niveau comme des structures.
NaN = struct.unpack('>d', b'\xff\xf8\x00\x00\x00\x00\x00\x00')[0]
Vous pouvez coder un str
à un bytes
objet.
>>> '\uFEFF'.encode('UTF-8')
b'\xef\xbb\xbf'
et vous pouvez décoder un bytes
en un str
.
>>> b'\xE2\x82\xAC'.decode('UTF-8')
'€'
mais vous on ne peut 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'...'
prête quelque peu à confusion en ce qu'elle permet aux octets 0x01-0x7F d'être spécifiés avec des caractères ASCII au lieu de nombres hexadécimaux.
>>> b'A' == b'\x41'
True
mais je dois souligner, un caractère n'est pas un octet .
>>> 'A' == b'A'
False
En Python 2.x
pré-3.0 les versions de Python manquaient de ce genre de distinction entre texte et données binaires. Au lieu de cela, il y avait:
-
unicode
=u'...'
Alphabets = séquence de caractères Unicode = 3.xstr
-
str
='...'
Alphabets = séquences d'octets et de caractères confondus- habituellement du texte, encodé dans un encodage non spécifié.
- mais aussi utilisé pour représenter des données binaires comme la sortie
struct.pack
.
, afin de faciliter les 2.x-3.la transition x, la syntaxe littérale b'...'
a été rétroportée en Python 2.6, afin de permettre de distinguer les chaînes binaires (qui devraient être bytes
en 3.x) à partir de chaînes de texte (qui devraient être str
en 3.x). Le préfixe b
ne fait rien en 2.x, mais dit au script 2to3
de ne pas le convertir en chaîne Unicode en 3.x.
donc oui, b'...'
les littérales en Python ont le même but que dans PHP.
aussi, juste par curiosité, sont là plus de symboles que les b et u qui font d'autres choses?
le préfixe r
crée une chaîne brute (par exemple, r'\t'
est un antislash + t
au lieu d'un onglet), et les Triple guillemets '''...'''
ou """..."""
permettent des lignes littérales multilignes.
le b indique une chaîne d'octets.
Octets sont les données réelles. Les cordes sont une abstraction.
si vous aviez un objet de chaîne à plusieurs caractères et que vous preniez un seul caractère, ce serait une chaîne, et sa taille pourrait être supérieure à 1 octet selon l'encodage.
si vous prenez 1 octet avec une chaîne de bytes, vous obtiendrez une seule valeur de 8 bits de 0-255 et cela pourrait ne pas représenter un caractère complet si ces caractères sont dus à les encodages étaient > 1 octet.
TBH j'utiliserais des chaînes à moins d'avoir une raison spécifique de bas niveau pour utiliser des octets.
il le transforme en bytes
littéral (ou str
en 2.x), et est valide pour 2.6+.
le préfixe r
fait en sorte que les antislashs soient "sans interprétation" (non ignoré, et la différence fait matière).
voici un exemple où l'absence de 'b' lancerait une exception de typographe en 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
L'ajout d'un préfixe " b " réglerait le problème.
en plus de ce que d'autres ont dit, notez qu'un seul caractère en unicode peut se composer de plusieurs octets .
la façon dont fonctionne unicode est qu'il a pris l'ancien format ASCII (7-bit code qui ressemble à 0XXX xxxx) et a ajouté séquences multi-octets où tous les octets commencent par 1 (1xxx xxxx) pour représenter les caractères au-delà de ASCII de sorte Qu'Unicode serait rétro-compatible 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
du côté du serveur,si nous envoyons une réponse, elle sera envoyée sous forme de type octet.Donc il apparaîtra dans le client comme b'Response du serveur "
pour se 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())
puis il affichera
réponse du serveur