问题描述
我正在做一个项目,在该项目中我必须使用 python 执行一些字节操作,我想在继续之前了解一些基本原理。
t1 = b"\xAC\x42\x4C\x45\x54\x43\x48\x49\x4E\x47\x4C\x45\x59"
t2 = "\xAC\x42\x4C\x45\x54\x43\x48\x49\x4E\x47\x4C\x45\x59"
print("Adding b character before: ",t1)
print("Using bytes(str): ",bytes(t2,"utf-8"))
print("Using str.encode: ",t2.encode())
特别是,当我运行上面的代码时,我无法理解为什么控制台会打印这个:
C:\Users\Marco\PycharmProjects\codeTest\venv\Scripts\python.exe C:/Users/Marco/PycharmProjects/codeTest/msgPack/temp.py
Adding b character before: b'\xacBLETCHINGLEY'
Using bytes(str): b'\xc2\xacBLETCHINGLEY'
Using str.encode: b'\xc2\xacBLETCHINGLEY'
我想了解的是,如果我使用 bytes() 或 decode ,我会在值前面得到一个额外的“\\xc2” 。 这是什么意思? 这是应该出现的吗? 如果是这样,我怎样才能在不使用第一种方法的情况下摆脱它?
1楼
因为bytes
对象和str
对象是两个不同的东西。
前者代表一个字节序列,后者代表一个Unicode码点序列。
字节 172 和 unicode 代码点 172 之间存在巨大差异。
特别是,字节 172 没有对任何特别是 unicode 的内容进行编码。 另一方面,unicode 代码点 172 指的是以下字符:
>>> c = chr(172)
>>> print(c)
?
当然,它们对应的实际原始字节取决于编码。 使用 utf-8 它是一个两字节的编码:
>>> c.encode()
b'\xc2\xac'
在latin-1编码中,它是一个1字节:
>>> c.encode('latin')
b'\xac'
如果您想要原始字节,那么最精确/最简单的方法是使用字节文字。
2楼
在字符串文字中, \\xhh
(h 是一个十六进制数字)选择相应的 unicode 字符U+0000
到U+00FF
,其中 U+00AC 是 ? “非符号”。
编码为 utf-8 时,0x7F 以上的所有代码点都占用两个或更多字节。
\\xc2\\xac
是U+00AC
的 utf-8 编码。
>>> "\u00AC" == "\xAC"
True
>>> "\u00AC" == "?"
True
>>> "\xAC" == "?"
True
>>> "\u00AC".encode('utf-8')
b'\xc2\xac'
>>> "?".encode("utf-8")
b'\xc2\xac'