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

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

b'The string'

我想知道:

  1. 字符串前面的b字符是什么意思?
  2. 使用它的效果是什么?
  3. 什么情况适合使用它?

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

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

另外,只是出于好奇,是否有比bu更多的符号来做其他事情?

1032013 次浏览

引用Python 2. x留档

“b”或“B”的前缀在Python 2;它表示字面量应该变成字节字面量在Python 3中(例如,当代码是自动转换为2to3)。A“u”或“b”前缀后面可以跟“r”前缀。

Python 3留档表示:

字节文字总是以'b'或'B'为前缀;它们生成字节类型而不是str类型的实例。它们只能包含ASCII字符;数值为128或更大的字节必须用转义表示。

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

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

如果您有多字符字符串对象并且您使用单个字符,它将是一个字符串,并且它的大小可能超过1个字节,具体取决于编码。

如果使用字节字符串占用1个字节,您将获得0-255中的单个8位值,如果由于编码导致的这些字符>1个字节,则它可能不表示完整字符。

TBH我会使用字符串,除非我有一些特定的低级理由使用字节。

python3. x明确区分了类型:

如果您熟悉:

  • Java或C#,将str视为String,将bytes视为byte[]
  • SQL,将str视为NVARCHAR,将bytes视为BINARYBLOB
  • Windows注册表,将str视为REG_SZ,将bytes视为REG_BINARY

如果你熟悉C(++),那么忘记你所学的关于char和字符串的一切,因为字符不是字节。那个想法早就过时了。

当您想要表示文本时,可以使用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'

您可以将bytes解码为str

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

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

  • unicode=u'...'文字=Unicode字符序列=3. xstr
  • str='...'文字=混淆字节/字符的序列
    • 通常是文本,以某种未指定的编码编码。
    • 但也用于表示二进制数据,如struct.pack输出。

为了简化2. x到3. x的转换,b'...'字面语法被反向移植到Python 2.6,以允许区分二进制字符串(在3. x中应该是bytes)和文本字符串(在3. x中应该是str)。b前缀在2. x中什么也不做,但告诉2to3脚本不要在3. x中将其转换为Unicode字符串。

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

另外,只是出于好奇,有没有比b和u更多的符号其他的呢?

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

这里有一个例子,没有b会在Python 3. x中引发TypeError异常

>>> 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前缀将解决问题。

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

Unicode的工作方式是采用旧的ASCII格式(看起来像0xxx xxxx的7位代码)并添加多字节序列,其中所有字节以1(1xxx xxxx)开头以表示ASCII以外的字符,以便Unicode在ASCII中为向后兼容

>>> len('Öl')  # German word for 'oil' with 2 characters2>>> 'Öl'.encode('UTF-8')  # convert str to bytesb'\xc3\x96l'>>> len('Öl'.encode('UTF-8'))  # 3 bytes encode 2 characters !3

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

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

服务器文件:

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

客户端文件:

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

然后它将打印Response from server

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

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

{"key":"value"}返回值


FLASK:

这是flask中的一个示例。在终端行上运行此命令:

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

在烧瓶/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)

{'key':'value'}返回值

这个问题的答案是,它确实:

data.encode()

为了解码它(删除b,因为有时你不需要它)

使用:

data.decode()

b"hello"不是一个字符串(即使它看起来像一个),而是一个字节序列。它是一个由5个数字组成的序列,如果您将它们映射到字符表,则看起来像h e l l o。然而,值本身不是字符串,Python只是有一个方便的语法来使用文本字符而不是数字本身来定义字节序列。这为您节省了一些键入,并且通常字节序列旨在被解释为字符。然而,情况并非总是如此-例如,读取JPG文件将在b"..."中产生无意义的字母序列,因为JPG具有非文本结构。

.encode().decode()在字符串和字节之间进行转换。

bytes(somestring.encode())是我在python 3中使用的解决方案。

def compare_types():output = b'sometext'print(output)print(type(output))

somestring = 'sometext'encoded_string = somestring.encode()output = bytes(encoded_string)print(output)print(type(output))

compare_types()