微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python 2.7.6将单个“高”unicode代码点拆分为两个

作为 MySQL在遇到“高”(序数> = 2 ^ 16)代码点时截断unicode字符串的一种解决方法,我一直在使用一个逐步完成字符串的小 Python方法(字符串是序列,记住),ord( )在字符上,并通过替换其他内容或直接删除代码点来取代截断.这已经在许多使用Python 2.7.3的机器上运行(Ubuntu 12.04 LTS,一些Centos 6,混合32位和64位cpu,到目前为止还不重要).

我注意到在Python 2.7.6安装上,这会中断. Ascii字符和“低”代码点(序数< 2 ^ 16)表现如前.但是高代码点(> = 2 ^ 16)表现得非常奇怪. Python2.7.6似乎将它们视为两个代码点.这是一个基础知识的测试用例:

### "good" machine,Python2.7.3
$uname -a && echo $LANG
Linux *** 3.2.0-60-virtual #91-Ubuntu SMP Wed Feb 19 04:13:28 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
en_US.UTF-8
$python2.7
Python 2.7.3 (default,Feb 27 2014,19:58:35) 
[GCC 4.6.3] on linux2
Type "help","copyright","credits" or "license" for more information.
>>> utest = u'a\u0395\U0001f30e'    # three chars: ascii,"low" codepoint,"high" codepoint
>>> utest.__class__
<type 'unicode'>
>>> len(utest),hash(utest)
(3,1453079728409075183)
>>> list(utest)        # split into list of single chars
[u'a',u'\u0395',u'\U0001f30e']
>>> utest[2]   # trying to extract third char (high codepoint)
u'\U0001f30e'
>>> len(utest[2])
1
>>> "%x" % ord(utest[2])
'1f30e'

这是预期的行为.我用三个字符初始化一个unicode字符串. Python说它是三个字符,它可以“解决”第三个字符,返回单个预期的高代码点.如果我得到该代码点的序数,我会得到与原始转义序列中相同的数字.

现在是Python 2.7.6

### "bad" machine,Python 2.7.6
$uname -a && echo $LANG
Linux *** 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
en_US.UTF-8
$python2.7
Python 2.7.6 (default,Jan 29 2014,20:05:36)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help","credits" or "license" for more information.
>>> utest = u'a\u0395\U0001f30e'
>>> utest.__class__
<type 'unicode'>
>>> len(utest),hash(utest)    # !!!
(4,-2836525916470507760)

一个差异:Python 2.7.6表示utest的长度为4.哈希值也不同.下一个惊喜:

>>> list(utest)                # !!!
[u'a',u'\ud83c',u'\udf0e']

不仅长度表现得很奇怪,分裂成单个字符甚至更奇怪,因为高码点的两个“半”变成两个低码点,没有明显的数字关系 – 至少对我来说 – 对于原始码点.

通过序列索引来解决代码点表现出相同的破坏:

>>> utest[2]
u'\ud83c'

为了获得原始的高代码点,我现在必须使用两个字符的切片:

>>> utest[2:4]
u'\U0001f30e'

但是,如果不是很明显,Python2.7.6仍然在内部将其视为两个代码点.我没办法从中得到一个序数.

>>> len(utest[2:4])
2
>>> "%x" % ord(utest[2:4])
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
TypeError: ord() expected a character,but string of length 2 found

那么该怎么办?我的代码取决于unicode字符串中的代码点的序数.如果一个代码点有时真的是两个代码点,那么我的序数就会变得毫无意义,而我的代码也无法执行它的功能.

这种行为有理由吗?这是故意改变吗?
是否有一些配置旋钮我可以在Python内部或系统级别恢复旧的行为?猴子补丁?我不知道在哪里看.

不幸的是,我甚至无法将其缩小到精确的次要版本.我们有很多2.7.3,一些2.7.1和几个2.7.6安装.否2.7.4 / 2.7.5.我只能说,我在任何2.7.3安装上都没有遇到过这个问题.

额外信息:将字符串编码为utf8会产生两个Python版本完全相同的响应(相同的字符,相同的长度,相同的哈希值).再次解码编码的utf8仍然会让我回到正方形1(即它不是解决方法,行为在unicode空间中仍然存在分歧).

解决方法

您正在体验所谓的“代理对”.这些只发生在 narrow builds的python上,其中代码点在内部存储为UTF-16.您可以通过检查sys.maxunicode来确认您拥有的构建(它将是2 ** 16 – 1).

其他一些好的阅读是PEP 393,遗憾的是……对于python 3.3,不幸的是.

编辑:谷歌搜索解决方法. Full credit to @dan04.

def code_points(text):
    import struct
    utf32 = text.encode('UTF-32LE')
    return struct.unpack('<{}I'.format(len(utf32) // 4),utf32)

>>> len(utest)
4
>>> len(code_points(utest))
3

如果你只关心长度你可以做len(utest.encode(‘UTF-32LE’))// 4,但看起来你想做更多,所以也许上面的功能是有帮助的.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我最近重新拾起了计算机视觉,借助Python的opencv还有face_recognition库写了个简单的图像识别demo,额外定制了一些内容,原本想打包成exe然后发给朋友,不过在这当中遇到了许多小问题,都解决了,记录一下踩过的坑。 1、Pyinstaller打包过程当中出现warning,跟d
说到Pooling,相信学习过CNN的朋友们都不会感到陌生。Pooling在中文当中的意思是“池化”,在神经网络当中非常常见,通常用的比较多的一种是Max Pooling,具体操作如下图: 结合图像理解,相信你也会大概明白其中的本意。不过Pooling并不是只可以选取2x2的窗口大小,即便是3x3,
记得大一学Python的时候,有一个题目是判断一个数是否是复数。当时觉得比较复杂不好写,就琢磨了一个偷懒的好办法,用异常处理的手段便可以大大程度帮助你简短代码(偷懒)。以下是判断整数和复数的两段小代码: 相信看到这里,你也有所顿悟,能拓展出更多有意思的方法~
文章目录 3 直方图Histogramplot1. 基本直方图的绘制 Basic histogram2. 数据分布与密度信息显示 Control rug and density on seaborn histogram3. 带箱形图的直方图 Histogram with a boxplot on t
文章目录 5 小提琴图Violinplot1. 基础小提琴图绘制 Basic violinplot2. 小提琴图样式自定义 Custom seaborn violinplot3. 小提琴图颜色自定义 Control color of seaborn violinplot4. 分组小提琴图 Group
文章目录 4 核密度图Densityplot1. 基础核密度图绘制 Basic density plot2. 核密度图的区间控制 Control bandwidth of density plot3. 多个变量的核密度图绘制 Density plot of several variables4. 边
首先 import tensorflow as tf tf.argmax(tenso,n)函数会返回tensor中参数指定的维度中的最大值的索引或者向量。当tensor为矩阵返回向量,tensor为向量返回索引号。其中n表示具体参数的维度。 以实际例子为说明: import tensorflow a
seaborn学习笔记章节 seaborn是一个基于matplotlib的Python数据可视化库。seaborn是matplotlib的高级封装,可以绘制有吸引力且信息丰富的统计图形。相对于matplotlib,seaborn语法更简洁,两者关系类似于numpy和pandas之间的关系,seabo
Python ConfigParser教程显示了如何使用ConfigParser在Python中使用配置文件。 文章目录 1 介绍1.1 Python ConfigParser读取文件1.2 Python ConfigParser中的节1.3 Python ConfigParser从字符串中读取数据
1. 处理Excel 电子表格笔记(第12章)(代码下载) 本文主要介绍openpyxl 的2.5.12版处理excel电子表格,原书是2.1.4 版,OpenPyXL 团队会经常发布新版本。不过不用担心,新版本应该在相当长的时间内向后兼容。如果你有新版本,想看看它提供了什么新功能,可以查看Open