我正在一个项目中,我必须使用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()或进行解码,则在该值之前会得到一个额外的“ \ xc2”。这是什么意思?这应该出现吗?如果是这样,如何不使用第一种方法就摆脱它?
因为bytes
对象和str
对象是两个不同的事物。前者表示bytes的序列,后者代表unicode码点的序列。字节172和Unicode代码点172之间存在巨大差异。
特别是,字节172不会对任何内容进行特别的Unicode编码。另一方面,Unicode代码点172引用以下字符:
>>> c = chr(172)
>>> print(c)
¬
当然,它们实际对应的原始字节取决于编码。使用utf-8,它是两字节编码:
>>> c.encode()
b'\xc2\xac'
在拉丁文1编码中,它是1个字节:
>>> c.encode('latin')
b'\xac'
如果您想要原始字节,那么最精确/最简单的方法是使用字节字面量。
在字符串文字中,\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'