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

时间:2011-06-07 18:14:53

标签: python string unicode binary

显然,以下是有效的语法

my_string = b'The string'

我想知道:

  1. 字符串前面的b字符是什么意思?
  2. 使用它有什么影响?
  3. 使用它的适当情况是什么?
  4. 我在SO上找到了一个related question,但这个问题是关于PHP的,它说明b用来表示字符串是二进制的,而不是Unicode,这是需要的使代码与PHP版本兼容< 6,迁移到PHP 6.我不认为这适用于Python。

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

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

9 个答案:

答案 0 :(得分:519)

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。如果你熟悉C(++),那么就忘记你所学到的关于char和字符串的一切,因为一个字符不是字节。这个想法早已过时了。

如果要表示文字,请使用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' == b'A'
False

在Python 2.x

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

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

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

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

  

另外,出于好奇,还有   比b和u更多的符号   其他的事情?

r前缀会创建一个原始字符串(例如,r'\t'是反斜杠+ t而不是标签符号),以及三重引号'''...'''或{{1}允许多行字符串文字。

答案 1 :(得分:314)

引用the Python 2.x documentation

  

将忽略前缀'b'或'B'   Python 2;它表明了   literal应该成为字节文字   在Python 3中(例如,当代码是   自动转换为2to3)。一个   可以跟随'u'或'b'前缀   'r'前缀。

Python 3 documentation州:

  

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

答案 2 :(得分:15)

b表示字节串。

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

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

如果用一个字节字符串取1个字节,你将从0-255获得一个8位值,如果由于编码而导致的那些字符是&gt;它可能不代表一个完整的字符。 1个字节。

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

答案 3 :(得分:8)

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

r前缀会导致反斜杠“未解释”(不会被忽略,差异重要)。

答案 4 :(得分:7)

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

答案 5 :(得分:7)

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

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

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

客户端文件

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

然后它将打印

来自服务器的响应

答案 6 :(得分:2)

除了其他人所说的,请注意unicode 中的单个字符可以包含多个字节

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

答案 7 :(得分:0)

您可以使用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)

{'key':'value'}

答案 8 :(得分:0)

问题的答案是,确实如此:

data.encode()

并对其进行解码(请删除b,因为有时您不需要它)

使用:

data.decode())