0

0

Python Unicode字符串格式化中的一个陷阱

大家讲道理

大家讲道理

发布时间:2016-11-07 10:14:00

|

1659人浏览过

|

来源于php中文网

原创

今天帮同事研究一个莫名其妙的unicodedecodeerror时发现了python字符串格式化中的一个小陷阱,在此记录一下。原本的代码过于复杂,有太多与问题无关的东西,所以我在ipython里简单试验复现了问题,过程如下:

In [4]: a = '你好世界'
In [5]: print 'Say this: %s' % a
Say this: 你好世界
In [6]: print 'Say this: %s and say that: %s' % (a, 'hello world')
Say this: 你好世界 and say that: hello world
In [7]: print 'Say this: %s and say that: %s' % (a, u'hello world')
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
/home/jerry/ in ()
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 10: ordinal not in range(128)
In [8]: a
Out[8]: '\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c'

看到In [7]之后的那个很怪异的UnicodeDecodeError没?它和上一句的唯一区别是’hello world‘变成了一个unicode对象而非str对象。但问题是,’hello world’只是单纯的英文字符串,不包含任何ASCII之外的字符,怎么会无法decode呢?再仔细看看异常附带的message,里面提到了0xe4,这个显然不是’hello world‘里面的,所以只能怀疑那句中文了,In [8]把它的字节序列打印了出来,果然就是它,第一个就是0xe4。

看来在字符串格式化的时候Python试图将a decode成unicode对象,并且decode时用的还是默认的ASCII编码而非实际的UTF-8编码。那这又是怎么回事呢??下面继续我们的试验:

In [9]: 'Say this: %s' % 'hello'
Out[9]: 'Say this: hello'
In [10]: 'Say this: %s' % u'hello'
Out[10]: u'Say this: hello'

仔细看,In [9]中的’hello’是普通的字符串,结果也是字符串(str对象),而In [10]中的’hello’变成了unicode对象,格式化的结果也变成unicode了(注意结果开头的那个u)。

所以真相是这样的:Python在格式化字符串的时候有一些隐藏着的小动作:如果%s对应的参数里有unicode,那么最终的结果也是unicode。在这种情况下模版字符串以及所有的%s参数中的str都会被decode成unicode,然而这个decode是隐式的,用户无法指定其使用的charset,Python只能用默认的ASCII。如果正好里面有非ASCII编码的字符串,就完蛋了……

立即学习Python免费学习笔记(深入)”;

天龙企业网站管理系统 2008.net
天龙企业网站管理系统 2008.net

天龙企业网站管理系统,基于.net2.0+access开发,系统架构采用MVC设计模式,是一个十分优秀的.net企业管理系统。其中包括产品发布,新闻发布,企业简价,企业文化,下载中心,客户留言等功能。在V2.0 sp2 基础上再次升级: 1、修正了前台的投票调查功能。 2、增强系统安全性,增加了防SQL注入功能 3、修补了后台漏洞 4、增加了前台游客留言的字符过滤,自动过滤html格式以增强系统安

下载

看看Python文档怎么说的:

If format is a Unicode object, or if any of the objects being converted using the %s conversion are Unicode objects, the result will also be a Unicode object.

如果代码里混合着str和unicode,这种问题很容易出现。在同事的代码里,中文字符串是用户输入的,经过了正确的编码处理,是以UTF-8编码的str对象;但那个惹事的unicode对象,虽然其内容都是ASCII码,但其来源是sqlite3数据库查询的结果,而sqlite的API返回的字符串都是unicode对象,所以导致了这么怪异的结果。

Python 2的str和unicode真的挺坑爹,已经被它们害过好几次了。Python 3在这方面很有提升,期待它的全面普及!

相关文章

python速学教程(入门到精通)
python速学教程(入门到精通)

python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
菜鸟裹裹入口以及教程汇总
菜鸟裹裹入口以及教程汇总

本专题整合了菜鸟裹裹入口地址及教程分享,阅读专题下面的文章了解更多详细内容。

0

2026.01.22

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

56

2026.01.21

三角洲入口地址合集
三角洲入口地址合集

本专题整合了三角洲入口地址合集,阅读专题下面的文章了解更多详细内容。

51

2026.01.21

AO3中文版入口地址大全
AO3中文版入口地址大全

本专题整合了AO3中文版入口地址大全,阅读专题下面的的文章了解更多详细内容。

397

2026.01.21

妖精漫画入口地址合集
妖精漫画入口地址合集

本专题整合了妖精漫画入口地址合集,阅读专题下面的文章了解更多详细内容。

118

2026.01.21

java版本选择建议
java版本选择建议

本专题整合了java版本相关合集,阅读专题下面的文章了解更多详细内容。

3

2026.01.21

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

16

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

11

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 13.3万人学习

Django 教程
Django 教程

共28课时 | 3.4万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号