Python在unicode变量中使用非ascii字符或不带

2024-04-16 04:28:12 发布

您现在位置:Python中文网/ 问答频道 /正文

一个简单的例子:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import traceback

e_u = u'abc'
c_u = u'中国'

print sys.getdefaultencoding()
try:
    print e_u.decode('utf-8')
    print c_u.decode('utf-8')
except Exception as e:
    print traceback.format_exc()

reload(sys)
sys.setdefaultencoding('utf-8')
print sys.getdefaultencoding()
try:
    print e_u.decode('utf-8')
    print c_u.decode('utf-8')
except Exception as e:
    print traceback.format_exc()

输出:

^{pr2}$

几天来,当我想彻底理解python中的编解码器时,一些问题困扰着我,我想确定我的想法是正确的:

  1. ascii默认编码下,u'abc'.decode('utf-8')没有错误,但是{}有错误。在

    我想当做u'中国'.decode('utf-8')时,Python检查发现{}是unicode,所以它尝试做u'中国'.encode(sys.getdefaultencoding()),这会引起问题,异常是UnicodeEncodeError,解码时没有出错。在

    但是u'abc''abc'(<;128)具有相同的代码点,因此没有错误。

  2. 在python2.x中,Python内部如何存储变量值?如果字符串中的所有字符<;128,则视为ascii,如果>;128,则视为utf-8?在

    In [4]: chardet.detect('abc')
    Out[4]: {'confidence': 1.0, 'encoding': 'ascii'}
    
    In [5]: chardet.detect('abc中国')
    Out[5]: {'confidence': 0.7525, 'encoding': 'utf-8'}
    
    In [6]: chardet.detect('中国')
    Out[6]: {'confidence': 0.7525, 'encoding': 'utf-8'}
    

Tags: in错误sysasciioututfencodingabc
1条回答
网友
1楼 · 发布于 2024-04-16 04:28:12

简短回答

您必须使用encode(),或者不使用它。不要将decode()与unicode字符串一起使用,这是没有意义的。而且,sys.getdefaultencoding()在这里也没有任何帮助。在

冗长的回答,第一部分:如何正确地做?

如果您定义:

c_u = u'中国'

那么c_u已经是一个unicode字符串,也就是说,它已经被Python解释器使用-*- coding: utf-8 -*-声明从(源文件的)字节字符串解码为unicode字符串。在

如果执行:

^{pr2}$

您的字符串将被编码回UTF-8,并将该字节字符串发送到标准输出。请注意,这通常是自动发生的,因此您可以将其简化为:

print c_u

长时间的回答,第二部分:c嫒u.decode()有什么问题?

如果执行c_u.decode(),Python将

  1. 尝试将对象(即unicode字符串)转换为字节字符串
  2. 尝试将该字节字符串解码为unicode字符串

请注意,如果您的对象首先是unicode字符串,那么这没有任何意义—您只需前后转换它。但为什么会失败呢?好吧,这是Python的一个奇怪的功能,第一步(1.),即从unicode字符串到字节字符串的任何隐式转换,通常都使用sys.getdefaultencoding(),这反过来又默认为ASCII字符集。换句话说

c_u.decode()

大致翻译为:

c_u.encode(sys.getdefaultencoding()).decode()

这就是它失败的原因。在

请注意,虽然您可能想更改默认编码,但不要忘记,其他第三方库可能包含类似的问题,如果默认编码与ASCII不同,则可能会中断。在

话虽如此,我坚信,如果Python一开始没有定义unicode.decode(),情况会更好。Unicode字符串已经被解码了,没有必要再次解码,尤其是Python的解码方式。在

相关问题 更多 >