python输出中文——如何在Windows控制台打印不乱码

文章介绍

用Python在控制台打印中文如何不会乱码,一直是困扰很多Pythoner的问题,甚至很多Python老手也经常犯难。原因就在于从一般网页、数据库或文本外来数据源上抓取过来的内容,需要经过正确的编解码才可以正常输出,而Python的编解码机制比较复杂,没有深入思考的话经常遇到调试错误。这篇文章介绍了最常见的几种输出中文的情况,编译平台为Windows控制台,Python版本为2.7.9

文章中一些内容参考了点击打开链接 感谢原作者分享。


预备知识

str和unicode

首先需要弄清楚str和unicode的区别。str是字节串,由unicode经过编码(encode)后的字节组成的unicode才是真正意义上的字符串,由字符组成在编程过程中,必须搞明白要处理的是str还是unicode, 使用对的处理方法(str.decode/unicode.encode)。一个简单的原则是:不要对str使用encode,不要对unicode使用decode(事实上str可以使用encode的,但不建议这么做,这里就不再赘述了。

用下面的代码判断是否为unicode/str:

<pre name="code" class="python">-*- coding=utf-8 -*-
isinstance(u'哈哈你好', unicode)
isinstance('哈哈你好',str)

 打印结果均为True。 

utf-8还是gbk

这两种都是中文的编码方式,选择其中哪一种都可以,但要注意的是必须同一项目中都统一使用,不能混合使用。

头部声明coding=utf-8, a = ‘中文‘ 其编码为utf-8

若头部声明coding=gb2312, a = ‘中文‘ 其编码为gbk

 同一项目中所有源文件头部统一一个编码,并且声明的编码要和源文件保存的编码一致(编辑器相关)

PS:在源代码用作处理的硬编码字符串,统一用unicode

将其类型和源文件本身的编码隔离开, 独立无依赖方便流程中各个位置处理。

代码实现

1. 最简单的情况,直接在代码行输出中文,即中文字符串不是保存在变量里的,如下即可实现:

print u'哈哈你好'
这里是把中文字符串'哈哈你好'解码成unicode字符串了,如果直接print '哈哈你好'则会显示乱码

2. 如果中文字符串是保存在字符串变量里,则 按照下面的方式实现:

string='哈哈你好'
print string.decode('UTF-8')
原理其实是跟第一种情况一样的,把中文字符串'哈哈你好'解码成unicode字符串了

3. 再复杂一点,中文字符串是保存在元组、列表或者字典里应该怎么输出呢?因为只有str对象才能调用decode方法,tuple/list/dict调用decode会报错,或许你会说把这些对象转换成str对象再调用decode,但那样很麻烦且程序效率不高。可以调用json模块的dumps方法,如下:

t_tuple=('哈哈','你好')
t_list=['哈哈','你好']
t_dict={1:'哈哈',2:'你好'}
print json.dumps(t_tuple,encoding='UTF-8',ensure_ascii=False)
print json.dumps(t_list,encoding='UTF-8',ensure_ascii=False)
print json.dumps(t_dict,encoding='UTF-8',ensure_ascii=False)
要注意dumps方法里的两个参数

完整代码和打印结果

# -*- coding:UTF-8 -*-
###测试python输出中文是否乱码
import json

print u'哈哈你好'

string='哈哈你好'
print string.decode('UTF-8')

<pre name="code" class="python">t_tuple=('哈哈','你好')
t_list=['哈哈','你好']
t_dict={1:'哈哈',2:'你好'}
print json.dumps(t_tuple,encoding='UTF-8',ensure_ascii=False)
print json.dumps(t_list,encoding='UTF-8',ensure_ascii=False)
print json.dumps(t_dict,encoding='UTF-8',ensure_ascii=False)
 在Windows控制台运行Python程序,输出结果为: 

5种类型的中文输出均可以不乱码显示。

常见报错处理

1. win7控制台打印报错——UnicodeEncodeError: ‘gbk’ codec can’t encode character u’\u200e’ in position 43: illegal multibyte sequence

(1)出现UnicodeEncodeError –> 说明是Unicode编码时候的问题;

(2) ‘gbk’ codec can’t encode character –> 说明是将Unicode字符编码为GBK时候出现的问题;

此时,往往最大的可能就是,本身Unicode类型的字符中,包含了一些无法转换为GBK编码的一些字符。

解决办法是:

  • 方案1:

在对unicode字符编码时,添加ignore参数,忽略无法无法编码的字符,这样就可以正常编码为GBK了。

对应代码为:

gbkTypeStr = unicodeTypeStr.encode(“GBK“, ‘ignore’);

  • 方案2:

或者,将其转换为GBK编码的超集GB18030 (即,GBK是GB18030的子集)

gb18030TypeStr = unicodeTypeStr.encode(“GB18030“);
对应的得到的字符是GB18030的编码。





©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页