京公网安备 11010802034615号
经营许可证编号:京B2-20210330
python实现unicode转中文及转换默认编码的方法
本文实例讲述了python实现unicode转中文及转换默认编码的方法。分享给大家供大家参考,具体如下:
一、在爬虫抓取网页信息时常需要将类似"\u4eba\u751f\u82e6\u77ed\uff0cpy\u662f\u5cb8"转换为中文,实际上这是unicode的中文编码。可用以下方法转换:
1、
>>> s = u'\u4eba\u751f\u82e6\u77ed\uff0cpy\u662f\u5cb8'
>>> print s
人生苦短,py是岸
2、
>>> s = r'\u4eba\u751f\u82e6\u77ed\uff0cpy\u662f\u5cb8'
>>> s = s.decode('unicode_escape')
>>> print s
人生苦短,py是岸
二、另外,在python2的字符编码问题时常会遇到“UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)”的编码错误。
而用以下方法通常可以解决:
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
此方法是将Python2的默认编码ASCII改为 utf-8。但此方法不是一劳永逸的,可能会使一些代码的行为变得怪异。
关于sys.setdefaultencoding('utf-8')的补充:
sys.setdefaultencoding('utf-8') 会导致的两个大问题
简单来说这么做将会使得一些代码行为变得怪异,而这怪异还不好修复,以一个不可见的 bug 存在着。下面我们举两个例子。
1. 编码错误
import chardet
def print_string(string):
try:
print(u"%s" % string)
except UnicodeError:
print u"%s" % unicode(byte_string, encoding=chardet.detect(string)['encoding'])
print_string(u"þ".encode("latin-1"))
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
print(key_in_dict('þ'))
输出:
$~ þ
$~ þ
在上面的代码中,默认的 ascii 编码无法解码,þ latin-1 编码 hex 表示是 c3 be ,显然是超出了只有128个字符的 ascii 码集的,引发 UnicodeError 异常,进入异常处理。异常处理则会根据编码探测,用最可能的编码来解码,会比较靠谱地输出 þ 。
而一旦我们将 defaultencoding 设置为 utf-8,因为 utf-8 的字符范围是完全覆盖 latin-1,因此,会直接使用 utf-8 进行解码。c3 be 在 utf-8 中,是 þ。于是我们打印出了完全不同的字符。
可能你们会说我们不会写这样的代码。如果我们写了也会做修正。但如果是第三方库这么写了呢?项目依赖的第三方库就这么 bug 了。如果你不依赖第三方库,那么下面这个 bug,还是逃不过。
2. dictionray 行为异常
假设我们要从一个 dictionary 里查找一个 key 是否存在,通常来说,有两种可行方法。
#-*- coding: utf-8 -*-
d = {1:2, '1':'2', '你好': 'hello'}
def key_in_dict(key)
if key in d:
return True
return False
def key_found_in_dict(key):
for _key in d:
if _key == key:
return True
return False
我们对比下改变系统默认编码前后这俩函数的输出有什么不同。
#-*- coding: utf-8 -*-
print(key_in_dict('你好'))
print(key_found_dict('你好'))
print(key_in_dict(u'你好'))
print(key_found_in_dict(u'你好'))
print('------utf-8------')
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
print(key_in_dict('你好'))
print(key_found_dict('你好'))
print(key_in_dict(u'你好'))
print(key_found_in_dict(u'你好'))
输出:
$~ True
$~ True
$~ False
$~ False
$~ ------utf-8------
$~ True
$~ True
$~ False
$~ True
可以看到,当默认编码改了之后,两个函数的输出不再一致。
dict 的 in 操作符将键做哈希,并比较哈希值判断是否相等。对于 ascii 集合内的字符来说,不管是字节字符类型还是还是 unicode 类型,其哈希值是一样的,如 u'1' in {'1':1} 会返回 True,而超出 ascii 码集的字符,如上例中的 '你好',它的字节字符类型的哈希与 unicode 类型的哈希是不一样的。
而 == 操作符则是做了一次转换,将字节字符(byte string,上面的 '你好')转换成 unicode(u'你好') 类型,然后对转换后的结果做比较。在 ascii 系统默认编码中,'你好'转换成 Unicode 会产生 Warning: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal,因为超出码集无法转换,系统会默认其不相等。当系统编码被我们手动改为 utf-8 后,这个禁忌则被解除,'你好' 能够顺利被转换成 unicode,最后的结果就是,in 和 == 行为不再一致。
问题的根源:Python2 中的 string
Python 为了让其语法看上去简洁好用,做了很多 tricky 的事情,混淆 byte string 和 text string 就是其中一例。
在 Python 里,有三大类 string 类型,unicode(text string),str(byte string,二进制数据),basestring,是前两者的父类。
其实,在语言设计领域,一串字节(sequences of bytes)是否应该当做字符串(string)一直是存在争议的。我们熟知的 Java 和 C# 投了反对票,而 Python 则站在了支持者的阵营里。其实我们在很多情况下,给文本做的操作,比如正则匹配、字符替换等,对于字节来说是用不着的。而 Python 认为字节就是字符,所以他们俩的操作集合是一致的。
然后进一步的,Python 会在必要的情况下,尝试对字节做自动类型转换,例如,在上文中的 ==,或者字节和文本拼接时。如果没有一个编码(encoding),两个不同类型之间的转换是无法进行的,于是,Python 需要一个默认编码。在 Python2 诞生的年代,ASCII 是最流行的(可以这么说吧),于是 Python2 选择了 ASCII。然而,众所周知,在需要需要转换的场景,ASCII 都是没用的(128个字符,够什么吃)。
在历经这么多年吐槽后,Python 3 终于学乖了。默认编码是 Unicode,这也就意味着,做所有需要转换的场合,都能正确并成功的转换。
最佳实践
说了这么多,如果不迁移到 Python 3,能怎么做呢?
有这么几个建议:
所有 text string 都应该是 unicode 类型,而不是 str,如果你在操作 text,而类型却是 str,那就是在制造 bug。
在需要转换的时候,显式转换。从字节解码成文本,用 var.decode(encoding),从文本编码成字节,用 var.encode(encoding)。
从外部读取数据时,默认它是字节,然后 decode 成需要的文本;同样的,当需要向外部发送文本时,encode 成字节再发送。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
在神经网络模型搭建中,“最后一层是否添加激活函数”是新手常困惑的关键问题——有人照搬中间层的ReLU激活,导致回归任务输出异 ...
2025-12-05在机器学习落地过程中,“模型准确率高但不可解释”“面对数据噪声就失效”是两大核心痛点——金融风控模型若无法解释决策依据, ...
2025-12-05在CDA(Certified Data Analyst)数据分析师的能力模型中,“指标计算”是基础技能,而“指标体系搭建”则是区分新手与资深分析 ...
2025-12-05在回归分析的结果解读中,R方(决定系数)是衡量模型拟合效果的核心指标——它代表因变量的变异中能被自变量解释的比例,取值通 ...
2025-12-04在城市规划、物流配送、文旅分析等场景中,经纬度热力图是解读空间数据的核心工具——它能将零散的GPS坐标(如外卖订单地址、景 ...
2025-12-04在CDA(Certified Data Analyst)数据分析师的指标体系中,“通用指标”与“场景指标”并非相互割裂的两个部分,而是支撑业务分 ...
2025-12-04每到“双十一”,电商平台的销售额会迎来爆发式增长;每逢冬季,北方的天然气消耗量会显著上升;每月的10号左右,工资发放会带动 ...
2025-12-03随着数字化转型的深入,企业面临的数据量呈指数级增长——电商的用户行为日志、物联网的传感器数据、社交平台的图文视频等,这些 ...
2025-12-03在CDA(Certified Data Analyst)数据分析师的工作体系中,“指标”是贯穿始终的核心载体——从“销售额环比增长15%”的业务结论 ...
2025-12-03在神经网络训练中,损失函数的数值变化常被视为模型训练效果的“核心仪表盘”——初学者盯着屏幕上不断下降的损失值满心欢喜,却 ...
2025-12-02在CDA(Certified Data Analyst)数据分析师的日常工作中,“用部分数据推断整体情况”是高频需求——从10万条订单样本中判断全 ...
2025-12-02在数据预处理的纲量统一环节,标准化是消除量纲影响的核心手段——它将不同量级的特征(如“用户年龄”“消费金额”)转化为同一 ...
2025-12-02在数据驱动决策成为企业核心竞争力的今天,A/B测试已从“可选优化工具”升级为“必选验证体系”。它通过控制变量法构建“平行实 ...
2025-12-01在时间序列预测任务中,LSTM(长短期记忆网络)凭借对时序依赖关系的捕捉能力成为主流模型。但很多开发者在实操中会遇到困惑:用 ...
2025-12-01引言:数据时代的“透视镜”与“掘金者” 在数字经济浪潮下,数据已成为企业决策的核心资产,而CDA数据分析师正是挖掘数据价值的 ...
2025-12-01数据分析师的日常,常始于一堆“毫无章法”的数据点:电商后台导出的零散订单记录、APP埋点收集的无序用户行为日志、传感器实时 ...
2025-11-28在MySQL数据库运维中,“query end”是查询执行生命周期的收尾阶段,理论上耗时极短——主要完成结果集封装、资源释放、事务状态 ...
2025-11-28在CDA(Certified Data Analyst)数据分析师的工具包中,透视分析方法是处理表结构数据的“瑞士军刀”——无需复杂代码,仅通过 ...
2025-11-28在统计分析中,数据的分布形态是决定“用什么方法分析、信什么结果”的底层逻辑——它如同数据的“性格”,直接影响着描述统计的 ...
2025-11-27在电商订单查询、用户信息导出等业务场景中,技术人员常面临一个选择:是一次性查询500条数据,还是分5次每次查询100条?这个问 ...
2025-11-27