关于python:”b”字符在字符串文本前面做什么?

What does the 'b' character do in front of a string literal?

显然,以下是有效的语法

1
my_string = b'The string'

我想知道:

  • 字符串前面的b字符是什么意思?
  • 使用它的效果是什么?
  • 使用它的适当情况是什么?
  • 我在这里找到了一个相关的问题,但是这个问题是关于php的,它指出b用于指示字符串是二进制的,而不是unicode,当迁移到php 6时,代码需要与php<6的版本兼容。我认为这不适用于python。

    我在python站点上找到了关于使用同一语法中的u字符将字符串指定为unicode的文档。不幸的是,在文档中的任何地方都没有提到b字符。

    此外,出于好奇,是否有比bu更多的符号可以做其他事情?


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

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

    如果您熟悉Java或C语言,请将EDOCX1 1作为EDCOX1,8,EDCX1,0作为EDCOX1,10。如果您熟悉SQL,可以将str想象为NVARCHARbytes想象为BINARYBLOB。如果您熟悉Windows注册表,可以将str视为REG_SZbytes视为REG_BINARY。如果你熟悉C(++),那么就忘记你所学的关于char和字符串的一切,因为字符不是字节。这个想法早就过时了。

    当您想表示文本时,可以使用str

    1
    print('???? ????')

    当您想要表示像结构这样的低级二进制数据时,可以使用bytes

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

    可以将str编码为bytes对象。

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

    你可以把一个bytes解码成一个str

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

    但是你不能随意混合这两种类型。

    1
    2
    3
    4
    >>> 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。

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

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

    1
    2
    >>> 'A' == b'A'
    False

    在Python 2。

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

    • unicode=u'...'=unicode字符序列=3.x str
    • 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中的文本具有相同的用途。

    Also, just out of curiosity, are there
    more symbols than the b and u that do
    other things?

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


    引用python 2.x文档:

    A prefix of 'b' or 'B' is ignored in
    Python 2; it indicates that the
    literal should become a bytes literal
    in Python 3 (e.g. when code is
    automatically converted with 2to3). A
    'u' or 'b' prefix may be followed by
    an 'r' prefix.

    python 3文档说明:

    Bytes literals are always prefixed with 'b' or 'B'; they produce an instance of the bytes type instead of the str type. They may only contain ASCII characters; bytes with a numeric value of 128 or greater must be expressed with escapes.


    b表示字节字符串。

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

    如果您有多个字符串对象,并且只取了一个字符,那么它将是一个字符串,并且根据编码的不同,它的大小可能超过1个字节。

    如果用一个字节字符串取1个字节,您将从0-255中得到一个8位的值,如果由于编码而产生的字符大于1个字节,那么它可能不代表完整的字符。

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


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

    r前缀导致反斜杠"未解释"(不被忽略,并且差异很重要)。


    下面是一个例子,其中缺少"b"会在python 3.x中引发typeerror异常。

    1
    2
    3
    4
    5
    >>> 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"前缀可以解决问题。


    从服务器端,如果我们发送任何响应,它将以字节类型的形式发送。"服务器响应"

    为了去掉b"…",只需使用下面的代码服务器文件

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

    客户端文件

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

    然后打印出来

    来自服务器的响应


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

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

    1
    2
    3
    4
    5
    6
    >>> 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