bytes()和b''之间的区别

时间:2019-09-04 09:13:57

标签: python python-3.x bytestream

我有以下str
"\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"

这来自文件名:Расшифровка_RootKit.com_63k.txt

我的问题是无法将第一个str还原为第二个。我已经尝试了一些方法,例如使用en/decode()bytes() etc ,但是我没有进行管理。

我注意到的一件事是b''和bytes()具有不同的输出:

path = "\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
bpath = bytes(path, "UTF-8")
print(bpath.decode("UTF-8"))
print(b"\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt".decode('utf8'))

结果:

РаÑÑиÑ
         Ñовка_RootKit.com_63k.txt
Расшифровка_RootKit.com_63k.txt

所以我想知道b''bytes()有什么区别;也许它将帮助我解决我的问题!

4 个答案:

答案 0 :(得分:3)

b''是一个前缀,它导致以下字符串被解释为bytes型对象。 bytes函数接受一个字符串并返回一个bytes对象。

print(b"\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt".decode

这有效,因为您正在解码字节对象。

path = "\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
bpath = bytes(path, "UTF-8")
print(bpath.decode("UTF-8"))

这无法按预期工作,因为您将path视为字符串,然后将其转换为字节对象,然后尝试对输出结果进行解码。

答案 1 :(得分:2)

您可能想将解决方案与latin1一起使用,请首先滚动到该答案。如果您不小心复制了字节内容并粘贴为字符串,则此答案有效。

如果要将它们转换回字节,请使用以下代码:

In [22]: path = "\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"

In [23]: bytes(map(ord, path)).decode('utf-8')
Out[23]: 'Расшифровка_RootKit.com_63k.txt'

说明非常简单,让我们使用字符串中的第一个字符:

In [40]: '\xd0'
Out[40]: 'Ð'

In [41]: b'\xd0'
Out[41]: b'\xd0'

如您所见,字符串将\xd0转换为数字为0xd0的Unicode字符,而字节只是将其解释为单个字节。

UTF-8对U+0080U+07FF之间的所有字符使用以下掩码:第一个字节为110xxxxx,第二个字节为10xxxxxx。这正是将字符串直接转换为字节时得到的:

In [43]: [bin(x) for x in '\xd0'.encode('utf-8')]
Out[43]: ['0b11000011', '0b10010000']

实际的符号代码是00011 + 010000(串联,而不是加法),即0xd0

In [44]: hex(int('00011010000', 2))
Out[44]: '0xd0'

要从字符中获取此数字,我们可以使用ord

In [45]: hex(ord('\xd0'))
Out[45]: '0xd0'

然后将其应用于整个字符串并将其转换回字节:

In [46]: bytes(map(ord, path)).decode('utf-8')
Out[46]: 'Расшифровка_RootKit.com_63k.txt'

请注意,如果由于某些原因您的字符串字符不适合字节,上述代码将引发错误:

In [47]: bytes([ord(chr(256))])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-49-5555e18dbece> in <module>
----> 1 bytes([ord(chr(256))])

ValueError: bytes must be in range(0, 256)

答案 2 :(得分:2)

要转换您的字符串,只需使用在字节和字符之间具有1到1映射的“ latin1”将其编码为字节,然后使用“ utf8”进行解码:

s = "\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"

s.encode('latin1').decode('utf8')

# 'Расшифровка_RootKit.com_63k.txt'

答案 3 :(得分:1)

path变量是一个字符串(不是字节)。 使用方法bytes()时,您会将其解码为字节,该字节将返回b'\xc3\x90\xc2\xa0\xc3\x90\xc2\xb0\xc3\x91\xc2\x81\xc3\x91\xc2\x88\xc3\x90\xc2\xb8\xc3\x91\xc2\x84\xc3\x91\xc2\x80\xc3\x90\xc2\xbe\xc3\x90\xc2\xb2\xc3\x90\xc2\xba\xc3\x90\xc2\xb0_RootKit.com_63k.txt'

但是当您写b"\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"时,您指的是Расшифровка_RootKit.com_63k.txt的Bytes值