python中unicode字符串的补充代码点

python中unicode字符串的补充代码点,python,unicode,python-2.x,supplementary,Python,Unicode,Python 2.x,Supplementary,unichr(0x10000)在编译cpython时,如果没有--启用unicode=ucs4,则会出现ValueError失败 是否有一个语言内置函数或核心库函数可以将任意unicode标量值或代码点转换为unicode字符串,无论程序运行在哪种类型的python解释器上,该字符串都能正常工作?是的,给您: >>> unichr(0xd800)+unichr(0xdc00) u'\U00010000' 需要理解的关键点是unichr()在Python解释器的字符串编码中将整

unichr(0x10000)
在编译cpython时,如果没有
--启用unicode=ucs4
,则会出现
ValueError
失败

是否有一个语言内置函数或核心库函数可以将任意unicode标量值或代码点转换为
unicode
字符串,无论程序运行在哪种类型的python解释器上,该字符串都能正常工作?

是的,给您:

>>> unichr(0xd800)+unichr(0xdc00)
u'\U00010000'
需要理解的关键点是
unichr()
在Python解释器的字符串编码中将整数转换为单个代码单元。上面写着

返回一个字符的Unicode字符串,其Unicode代码为整数i。。。。参数的有效范围取决于Python的配置方式–它可以是UCS2[0..0xFFFF]或UCS4[0..0x10FFFF]<否则将引发代码>值错误

我对“一个字符”加了强调,他们的意思是

我假设您使用的是Python2.x。Python 3.x解释器没有内置的
unichr()
函数。取而代之的是

返回表示字符的字符串,该字符的Unicode码点为整数i。。。。参数的有效范围为0到1114111(以16为基数的0x10FFFF)

请注意,返回值现在是一个未指定长度的字符串,而不是具有单个代码单元的字符串。因此,在Python3.x中,
chr(0x10000)
的行为与您预期的一样。它“将任意unicode标量值或代码点转换为
unicode
字符串,无论程序运行在哪种python解释器上,该字符串都有效”

但是回到Python2.x。如果使用
unichr()

您可以使用一个函数来隔离此感知,该函数尝试对标量值执行
unichr()
,捕获
ValueError
,然后使用相应的UTF-16代理项对重试:

def unichr_supplemental(scalar):
     try:
         return unichr(scalar)
     except ValueError:
         return unichr( 0xd800 + ((scalar-0x10000)//0x400) ) \
               +unichr( 0xdc00 + ((scalar-0x10000)% 0x400) )

>>> unichr_supplemental(0x41),len(unichr_supplemental(0x41))
(u'A', 1)
>>> unichr_supplemental(0x10000), len(unichr_supplemental(0x10000))
(u'\U00010000', 2)
但您可能会发现,只需将标量转换为UTF-32字节
字符串中的4字节UTF-32值,并将该字节
字符串
解码为
unicode
字符串就更容易了:

>>> '\x00\x00\x00\x41'.decode('utf-32be'), \
... len('\x00\x00\x00\x41'.decode('utf-32be'))
(u'A', 1)
>>> '\x00\x01\x00\x00'.decode('utf-32be'), \
... len('\x00\x01\x00\x00'.decode('utf-32be'))
(u'\U00010000', 2)

上面的代码在Python2.6.7上进行了测试,使用UTF-16编码Unicode字符串。我并没有在Python2.xIntepreter上对Unicode字符串使用UTF-32编码进行测试。但是,它应该在任何具有Unicode字符串实现的Python 2.x解释器上都能正常工作。

我很确定这是不可能做到的,这也是您不能信任其他人的Python在任意Unicode数据上运行的原因之一。然而,这似乎在v3.3版本中得到了修复。如果您想要抽象Unicode,您必须等待下一个版本,或者使用更强大的平台。@tchrist,谢谢。是 啊我需要学习Python3.x。它似乎解决了许多小的困惑。我(大部分)不同意@tchrist的观点,认为这是不可能的;请看下面我的答案,答案很好。请注意,最新的Python版本消除了整个“广泛构建”问题,这对这些事情也有很大帮助。如果您运行的是早期版本,那么您当然应该使用“广泛构建”。关于2.x,您是正确的。感谢您对规格的说明以及它们之间差异的解释。