字符串文字前的'b'字符做什么?


830

显然,以下是有效的语法:

my_string = b'The string'

我想知道:

  1. 这是什么b字在前面的字符串是什么意思?
  2. 使用它有什么作用?
  3. 在什么情况下可以使用它?

我在SO上找到了一个相关的问题,但是这个问题是关于PHP的,它指出b用来表示字符串是二进制的,与Unicode相反,Unicode是使PHP <6版本兼容的代码所必需的,当迁移到PHP 6时。我认为这不适用于Python。

我确实在Python站点上找到了有关使用相同语法的字符将字符串指定为Unicode的文档u。不幸的是,它在该文档的任何地方都没有提到b字符。

而且,只是出于好奇,有没有比多符号bu是做其他事情?

Answers:


416

引用Python 2.x文档

在Python 2中,前缀'b'或'B'被忽略;它表示文字应在Python 3中变成字节文字(例如,当代码自动由2to3转换时)。前缀“ u”或“ b”后可以带有前缀“ r”。

Python 3中的文件状态:

字节字面量始终以“ b”或“ B”为前缀;它们产生字节类型的实例而不是str类型。它们只能包含ASCII字符;数值等于或大于128的字节必须用转义符表示。


4
因此,听起来Python <v3只会忽略这个额外的字符。在v3中会出现什么情况,您需要使用ab字符串而不是普通字符串?
Jesse Webb

5
@Gweebz-如果您实际上是以特定编码键入字符串,而不是使用Unicode转义符(例如b'\ xff \ xfe \ xe12'而不是'\ u32e1')。
熟练地

7
实际上,如果您是unicode_literals从导入的__future__,这将“逆转”此特定字符串的行为(在Python 2.x中)
Romuald Brunet 2013年

33
围绕引用的文档进行一些简单的语言叙述将使这成为更好的答案恕我直言
Hack-R

2
否则,是对已经了解它的人的答案。
拉斐尔·伊恩

676

Python 3.x明确区分了以下类型:

  • str= '...'文字= Unicode字符序列(UTF-16或UTF-32,取决于Python的编译方式)
  • bytes= b'...'文字=八位字节序列(0到255之间的整数)

如果你熟悉Java或C#,想到strStringbytes作为byte[]。如果您熟悉SQL,请认为stras NVARCHARbytesas BINARYBLOB。如果你熟悉Windows注册表,想到strREG_SZbytes作为REG_BINARY。如果您熟悉C(++),请忘记学习的所有知识char和字符串,因为CHARACTER不是BYTE。这个想法早已过时。

您可以使用str,当你想要表达的文字。

print('שלום עולם')

您可以使用bytes,当你想表示相同结构的低级别的二进制数据。

NaN = struct.unpack('>d', b'\xff\xf8\x00\x00\x00\x00\x00\x00')[0]

您可以编码一个str到一个bytes对象。

>>> '\uFEFF'.encode('UTF-8')
b'\xef\xbb\xbf'

您可以将a解码bytesstr

>>> b'\xE2\x82\xAC'.decode('UTF-8')
'€'

但是您不能随意混合使用这两种类型。

>>> 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

这种b'...'表示法有些令人困惑,因为它允许使用ASCII字符而不是十六进制数字指定字节0x01-0x7F。

>>> b'A' == b'\x41'
True

但是我必须强调,字符不是字节

>>> 'A' == b'A'
False

在Python 2.x中

Python 3.0之前的版本在文本和二进制数据之间缺乏这种区别。相反,有:

  • unicode= u'...'文字= Unicode字符序列= 3.xstr
  • str= '...'文字=混杂字节/字符的序列
    • 通常为文本,以某种未指定的编码进行编码。
    • 而且还用来表示二进制数据,如struct.pack输出。

为了简化从2.x到3.x的过渡,b'...'将原义语法反向移植到Python 2.6,以便区分二进制字符串(应bytes在3.x中)和文本字符串(应str在3中) 。X)。该b前缀在2.x中不执行任何操作,但告诉2to3脚本不要在3.x中将其转换为Unicode字符串。

因此,是的,b'...'Python中的文字具有与PHP中相同的目的。

另外,出于好奇,还有比b和u更多的符号可以执行其他操作吗?

r前缀创建原始字符串(例如,r'\t'是反斜杠+ t,而不是一个选项卡),和三引号'''...'''"""..."""允许多行字符串文字。


2
谢谢!在阅读以下句子后,我理解了它:“为了简化从2.x到3.x的过渡,将b'...'字面语法反向移植到Python 2.6,以允许区分二进制字符串(是3.x中的字节)(来自3.x中的str)。b前缀在2.x中不执行任何操作,但告诉2to3脚本不要将其转换为3.x中的Unicode字符串。”
tommy.carstensen

4
'A' == b'A' --> False检查真的清楚。其余的内容都很棒,但是到那时我还没有完全理解字节字符串不是真正的文本。
通配符

12
'שלום עולם' == 'hello world'
伊莱(Eli)

12
这比仅引用文档的已接受答案要清楚得多。对我而言,文档没有意义,因此在文档中提供进一步的上下文非常棒。谢谢!
rayryeng '18 -4-5

2
b“ some string” .decode('UTF-8'),我相信许多人都在寻找这一行
Marvin Thobejane 18/09/16

22

b表示字节字符串。

字节是实际数据。字符串是一种抽象。

如果您有多个字符的字符串对象并且使用了一个字符,则该字符串将是一个字符串,并且根据编码的不同,大小可能会超过1个字节。

如果使用1个字节和一个字节字符串,则您将获得0-255之间的单个8位值,并且如果由于编码而导致的那些字符大于1个字节,则它可能不表示完整的字符。

TBH我将使用字符串,除非我有一些特定的低级原因要使用字节。


16

从服务器端,如果我们发送任何响应,它将以字节类型的形式发送,因此它将在客户端中显示为 b'Response from server'

为了摆脱,b'....'只需使用以下代码:

服务器文件:

stri="Response from server"    
c.send(stri.encode())

客户端文件:

print(s.recv(1024).decode())

然后它将打印 Response from server


1
它没有解释Jesse Webb提出的问题!
Chandra Kanth '18

我是说如果不使用编码和解码方法,则字符串输出将以b''作为前缀,因为python将其作为字节类型而不是字符串类型。如果您不想获得类似b'的输出...请仅使用以上内容。您不了解什么?
Nani Chintha

实际上,这正是所问问题标题的答案:问:“ b'x'做什么?” 答:“确实会执行'x'.encode()”。剩下的问题想知道的不只是这个,而是标题得到了回答。
Michael Erickson

10

这是一个示例,其中缺少bTypeError在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

添加b前缀将解决此问题。


9

它将其转换为bytes文字(或str在2.x中),并且对于2.6+有效。

r前缀导致反斜杠需要“不解释”(不被忽略,差异确实物质)。


根据aix答案中引用的文档,这听起来是错误的。在B将在其他Python版本被忽略小于3
杰西·韦伯

2
str无论哪种方式,它在2.x中都是a ,因此可以说它被忽略了。unicode_literals__future__模块导入时,区别很重要。
伊格纳西奥·巴斯克斯

6

除了其他人所说的以外,请注意unicode中的单个字符可以由多个字节组成

unicode的工作方式是采用旧的ASCII格式(7位代码,看起来像0xxx xxxx),并添加了多字节序列,其中所有字节均以1(1xxx xxxx)开头,以表示ASCII以外的字符,以便Unicode 向后-与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

2

您可以使用JSON将其转换为字典

import json
data = b'{"key":"value"}'
print(json.loads(data))

{“核心价值”}


烧瓶:

这是烧瓶的一个例子。在终端行上运行此命令:

import requests
requests.post(url='http://localhost(example)/',json={'key':'value'})

在flask / 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)

{'核心价值'}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.