首页 文章

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

提问于
浏览
520

显然,以下是有效的语法

my_string = b'The string'

我想知道:

  • 字符串前面的 b 字符是什么意思?

  • 使用它有什么影响?

  • 使用它的适当情况是什么?

我在SO上找到了一个related question,但是这个问题是关于PHP的,它说明_776608用于表示字符串是二进制的,而不是Unicode,这是代码与PHP版本兼容所需的代码<6 ,当迁移到PHP 6.我不认为这适用于Python .

我确实在Python网站上找到this documentation关于在相同语法中使用 u 字符来将字符串指定为Unicode . 不幸的是,它没有在该文档中的任何地方提及 b 字符 .

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

7 回答

  • 456

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

    r 前缀导致反斜杠为"uninterpreted"(不会被忽略,差别确实很重要) .

  • 14

    这是一个例子,缺少'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'前缀可以解决问题 .

  • 282

    除了别人说的话,请注意unicode中的单个字符 can consist of multiple bytes .

    unicode的工作方式是采用旧的ASCII格式(7位代码看起来像0xxx xxxx)并添加multi-bytes sequences所有字节以1(1xxx xxxx)开头表示ASCII以外的字符,以便Unicode为backwards-compatible和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
    
  • 8

    引用the Python 2.x documentation

    Python 2中忽略前缀'b'或'B';它表示文字应该成为Python 3中的字节文字(例如,当代码自动转换为2to3时) . 'u'或'b'前缀后面可以跟一个'r'前缀 .

    Python 3 documentation说:

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

  • 2

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

    • str = '...' literals =一系列Unicode字符(UTF-16或UTF-32,具体取决于Python的编译方式)

    • bytes = b'...' literals =一个八位字节序列(0到255之间的整数)

    如果您熟悉Java或C#,请将 str 视为 String ,将 bytes 视为 byte[] . 如果您熟悉SQL,请将 str 视为 NVARCHAR ,将 bytes 视为 BINARYBLOB . 如果您熟悉Windows注册表,请将 str 视为 REG_SZ ,将 bytes 视为 REG_BINARY . 如果你're familiar with C(++), then forget everything you'已经了解 char 和字符串,因为 A CHARACTER IS NOT A BYTE . 这个想法早已过时 .

    如果要表示文本,请使用 str .

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

    如果要表示结构等低级二进制数据,请使用 bytes .

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

    您可以encode strbytes 对象 .

    >>> '\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 character is not a byte .

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

    在Python 2.x中

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

    • unicode = u'...' literals = Unicode字符序列= 3.x str

    • str = '...' literals =混淆的字节/字符序列

    • 通常是文本,以某种未指定的编码进行编码 .

    • 但也用于表示 struct.pack 输出等二进制数据 .

    为了简化2.x到3.x的转换, b'...' 文字语法被反向移植到Python 2.6,以便允许从文本字符串中区分二进制字符串(应该是 bytes 在3.x中)(应该是 str 在3.x) . b 前缀在2.x中没有任何作用,但是告诉 2to3 脚本不要将其转换为3.x中的Unicode字符串 .

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

    另外,出于好奇,是否有更多符号而不是b和u做其他事情?

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

  • 6

    b表示字节串 .

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

    如果您有多字符串对象并且您使用了单个字符,则它将是一个字符串,并且根据编码,它可能超过1个字节 .

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

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

  • 2

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

    为了摆脱b'....'只需使用下面的代码服务器文件

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

    客户端文件

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

    那么它会打印出来

    服务器响应

相关问题