📜  Python|可疑编码的 C 字符串 |第 2 组

📅  最后修改于: 2022-05-13 01:54:54.033000             🧑  作者: Mango

Python|可疑编码的 C 字符串 |第 2 组

扩展模块中的字符串处理是一个问题。扩展中的 C字符串可能不遵循Python通常期望的严格的 Unicode 编码/解码规则。因此,一些格式错误的 C 数据可能会传递给Python。一个很好的例子可能是与文件名等低级系统调用相关联的 C字符串。例如,如果系统调用将损坏的字符串返回给无法正确解码的解释器,会发生什么情况。

通常,Unicode 错误通常通过指定某种错误策略来处理,例如严格、忽略、替换或类似的东西。然而,这些策略的缺点是它们不可挽回地破坏了原始字符串内容。
例如,如果示例中的格式错误的数据使用这些策略之一进行解码,您将获得如下所示的结果 -

代码#1:

raw = b'Spicy Jalape\xc3\xb1o\xae'
  
print (raw.decode('utf-8', 'ignore'))
  
print (raw.decode('utf-8', 'replace'))

输出 :

'Spicy Jalapeño'
'Spicy Jalapeño?'

surrogateescape错误处理策略采用所有不可解码的字节并将它们转换为代理对的低半部分(\udcXX,其中 XX 是原始字节值)。

代码#2:

print (raw.decode('utf-8', 'surrogateescape'))

输出 :

'Spicy Jalapeño\udcae'

像 \udcae 这样的孤立的低代理字符永远不会出现在有效的 Unicode 中。因此,该字符串在技术上是非法的表示。事实上,如果试图将它传递给执行输出的函数,就会出现编码错误。

代码#3:

s = raw.decode('utf-8', 'surrogateescape')
print(s)

输出 :

Traceback (most recent call last):
File "", line 1, in 
UnicodeEncodeError: 'utf-8' codec can't encode 
character '\udcae' in position 14: surrogates not allowed

但是,允许代理转义的主要目的是允许格式错误的字符串从 C 传递到Python并返回到 C 而不会丢失任何数据。当再次使用 surrogateescape 对字符串进行编码时,代理字符将转回其原始字节。例如:

代码 #4:

print (s)
print(s.encode('utf-8', 'surrogateescape'))

输出 :

'Spicy Jalapeño\udcae'
b'Spicy Jalape\xc3\xb1o\xae'

作为一般规则,最好尽可能避免代理编码。如果使用正确的编码,代码将更加可靠。但是,有时在某些情况下,人们根本无法控制数据编码,并且不能随意忽略或替换坏数据,因为其他功能可能需要使用它。

最后一点,Python 的许多面向系统的函数,尤其是与文件名、环境变量和命令行选项相关的函数,都使用代理编码。例如,如果在包含不可解码文件名的目录上使用诸如os.listdir()之类的函数,它将作为带有代理转义符的字符串返回。