Python无法使用surrogateescape进行编码

时间:2015-08-08 20:40:26

标签: python unicode utf-16 surrogate-pairs

我在Python(3.4)中使用Unicode代理编码存在问题:

b'\xCC'

如果我没弄错的话,根据Python documentation

  

'surrogateescape':在解码时,用单个代理替换字节   代码范围从U + DC80到U + DCFF。然后将返回此代码   当使用'surrogateescape'错误处理程序时,进入相同的字节   编码数据时。

代码应该只生成源序列(driver.waitUntil(function() { return this.getTitle().then(function(title) { if(title === 'Google') { return true; } }); }); )。那么为什么会引发例外呢?

这可能与我的第二个问题有关:

  

版本3.4中更改:utf-16 *和utf-32 *编码器不再允许对代理代码点(U + D800-U + DFFF)进行编码。

(来自https://docs.python.org/3/library/codecs.html#standard-encodings

据我所知,在没有代理对的情况下,将一些代码点编码为UTF-16是不可能的。那背后的原因是什么呢?

2 个答案:

答案 0 :(得分:4)

此更改是因为 Unicode标准明确禁止此类编码。请参阅issue #12892,但显然surrogateescape错误处理程序无法与UTF-16或UTF-32一起使用,因为这些编解码器不兼容ASCII。

具体做法是:

  

我测试了utf_16_32_surrogates_4.patch:surrogateescape作为编码器   没有按预期工作。

>>> b'[\x00\x80\xdc]\x00'.decode('utf-16-le', 'ignore')
'[]'
>>> b'[\x00\x80\xdc]\x00'.decode('utf-16-le', 'replace')
'[�]'
>>> b'[\x00\x80\xdc]\x00'.decode('utf-16-le', 'surrogateescape')
'[\udc80\udcdc\uffff'
     

=>我期待'[\udc80\udcdc]'

响应:

  

是的,surrogateescape不能与ASCII不兼容的编码一起使用,也不能。首先,它不能表示从utf-16-le解码b'\x00\xd8'或从utf-32 *解码b'ABCD'的结果。这个问题值得分离问题(甚至是PEP)和关于Python-Dev的讨论。

我相信surrogateescape处理程序更适用于UTF-8数据;解码为UTF-16或UTF-32现在也适用它是一个很好的额外功能,但它显然无法在另一个方向工作。

答案 1 :(得分:1)

如果您使用surrogatepass(而不是surrogateescape),那么事情应该适用于Python 3.

请参阅:https://docs.python.org/3/library/codecs.html#codec-base-classes(表示surrogatepass允许对代理代码进行编码和解码(针对utf相关编码)。