2011-06-07 73 views
386

显然,以下是有效的语法'b'字符在字符串面前做了什么?

my_string = b'The string' 

我想知道:

  1. 是什么在前面的字符串这b字是什么意思?
  2. 使用它有什么影响?
  3. 什么是适当的情况下使用它?

我发现了一个related question就在这里SO,但问题是关于PHP虽然,它指出了b用于表示该字符串是二进制的,而不是为Unicode,这是需要的代码兼容从PHP < 6的版本迁移到PHP 6.我不认为这适用于Python。

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

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

回答

211

引述the Python 2.x documentation

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

Python 3.3 documentation状态:

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

+4

所以它听起来像Python 2011-06-07 19:05:18

+2

@Gweebz - 如果你真的用特定的编码输入一个字符串,而不是使用unicode转义(例如,'b'\ xff \ xfe \ xe12'而不是'\ u32e1')。 – detly 2011-06-08 02:44:49

+0

这是有道理的。我将把这个标记为公认的答案,但这里也有其他的好答案! – 2011-06-08 14:15:36

6

它将它变成bytes文字(或str 2.x),并且对于2.6+有效。

r前缀会导致反斜杠“未解释”(不会被忽略,并且差异确实是的问题)。

+0

根据aix答案中引用的文档,这听起来是错误的;除了3以外的Python版本,b将被忽略。 – 2011-06-07 19:06:14

+2

这将是2中的“str”。无论哪种方式,所以可以说它被忽略了。从'__future__'模块中导入'unicode_literals'时区别很重要。 – 2011-06-07 19:16:50

+0

对不起,我误解了你原来的陈述。你的回答是准确的。 – 2011-06-07 20:40:08

10

b表示一个字节串。

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

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

如果用了1个字节与字节的字符串,你会得到从0-255一个8位的值,如果由于编码这些字符是> 1个字节它可能无法代表一个完整的字符。

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

351

Python 3.x使得类型之间有明显的区别:

  • str = '...'文字= Unicode字符(UTF-16或UTF-32,这取决于Python的是如何被编译)
  • bytes的序列= b'...'文字=八位字节序列

如果你熟悉Java或C#(0和255之间的整数),认为strStringbytes作为byte[]。如果你熟悉SQL,认为strNVARCHARbytesBINARYBLOB。如果你熟悉Windows注册表,认为strREG_SZbytesREG_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'...'符号是因为它允许字节0x01-0x7F与ASCII字符,而不是十六进制数进行指定有点混乱。

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

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

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

在Python 2.x的

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

  • unicode = u'...'文字= Unicode字符序列= 3.x的str
  • str = '...'文字=混杂字节序列/字符
    • 一般文本,在一些编码未指定的编码。
    • 但也用于表示像struct.pack输出的二进制数据。

为了缓解在2.x到3.x的过渡中,b'...'文本语法被反向移植到Python 2.6,以便允许区分二进制字符串(这应该是在3 bytes。 x)来自文本字符串(在3.x中应该是str)。前缀b在2.x中不做任何处理,但会告知2to3脚本不要将其转换为3.x中的Unicode字符串。

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

而且,只是出于好奇,有没有 比B和U更多的符号是做其他事情 ?

r前缀创建原始字符串(例如,r'\t'是反斜杠+ t代替标签),和三引号'''...'''"""..."""允许多行字符串文字。

+9

+1谢谢您的详细解答!我希望在aix提供的足够信息让我认为他的答案是第一个正确的答案之前,这个标记就是正确的。 – 2011-06-08 14:14:49

+1

谢谢!我在阅读这些句子后明白了这一点:“为了缓解2.x到3.x的转换,b'...'文字语法被反向移植到Python 2.6,以便区分二进制字符串(应该在3.x中是字节(应该是3.x中的str).b前缀在2.x中没有做任何事情,但是告诉2to3脚本不要在3.x中将它转换为Unicode字符串。“ – 2013-09-08 03:46:50

+0

python版本信息解释非常有用。谢谢。 – 2015-01-23 12:28:11

6

下面是一个例子,其中没有“B”会抛出一个TypeError异常在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”字头将解决这个问题。

+1

有用评论fella,感谢未来 – 2015-10-30 06:05:13

0

除了别人的说法之外,请注意unicode 中的单个字符可以包含多个字节

unicode的工作方式是它采用了旧的ASCII格式(7位代码看起来像0xxx xxxx)并添加了multi-bytes sequences,其中所有字节都以1(1xxx xxxx)开头,表示Unicode之外的字符,以便Unicode带有ASCII的backwards-compatible

>>> 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 
相关问题