【原创】python中文编码问题深入分析(二):print打印中文异常及显示乱码问题分析与解决
在学习python以及在使用python进行项目开发的过程中,经常会使用print语句打印一些调试信息,这些调试信息中往往会包含中文,如果你使用python版本是python2.7,或许你也会遇到和我一样的问题:那就是print打印中文异常以及显示乱码问题。本文主要分析一下在linux下使用python2.7的print语句中文异常以及终端显示中文乱码问题的原因及解决办法。转载请注明出处,谢谢!
1.print打印显示的过程
  
图1. Print打印显示过程
Python2.7中调用print打印var 变量时,操作系统会对var做一定的字符处理:如果var是str类型的变量,则直接将var变量交付给终端进行显示;如果var变量是unicode类型,则操作系统首先将var编码成str类型的对象(编码格式取决于stdout的编码格式),然后再交由终端进行显示。在显示时,如果str类型的变量的编码方式和终端设置的编码方式不一致,很可能会出现乱码问题。
2.print中文字符出现错误问题
在python源码中print中文字符,时常会出现Non-ASCII character和UnicodeEncodeError两类错误。下面分别一一介绍。
2.1 Non-ASCII character错误
print.py源码示例(代码1):
import sys
print sys.getdefaultencoding()
a="测试"
b=u"测试"
print a
print b
这段代码试图在linux的终端打印变量a和b的值,但是在实际执行的过程中,会提示Non-ASCII character错误:
    
原因:该print.py的文件格式是utf-8(可以vi print.py,然后在命令模式下,输入:set fileencoding,查看文件的编码方式,)。“测试”对应的utf编码为:'\xe6\xb5\x8b\xe8\xaf\x95',由于print.py中含有中文,且print.py没有指定编码方式,python会按照系统的默认编码解析执行print.py(这里的系统默认编码是ascii,查看系统的默认编码,可以调用sys.getdefaultencoing()函数),因此会提示Non-ASCII character的错误。
解决办法:在print.py起始处,指定编码方式为utf-8,这样python在执行代码时,就知道要按照utf-8来解释执行代码了。代码2:
#coding=utf-8
import sys
print sys.getdefaultencoding()
a="测试"
b=u"测试"
print a
print b
运行结果如下:

2.2 UnicodeEncodeError问题
代码2在192.168.86.61上能正常运行,但是换到另一台机器192.168.86.157就不能正常运行了,现象如下:

从打印信息来看,print a可以正常输出,而print b就会出现UnicodeEncodeError错误,这是为什么呢??
根据第1节中的介绍,变量b是unicode类型的,操作系统会按照stdout的默认编码将b编码成str类型的变量,根据报错信息猜测系统stdout的默认编码是ascii,而ascii字符的范围是0-127,因此会报上述错误。而变量a是str类型,调用print时,不需要经过操作系统进行编码,所以能正常输出。
那么,如何验证157上的系统stdout的编码方式是不是ascii呢?可以通过sys.stdout.encoding查看stdout的编码方式,这里的输出结果是ANSI_X3.4-1968,其别名就是ASCII,哈哈,原来真的是这样。
那么,为什么在192.168.86.61上,print b就能正常被打印输出呢?想要知道原因,让我们查看一下192.168.86.61上的stdout的编码方式,通过sys.stdout.encoding查得stdout的编码方式为utf-8,unicode类型的变量b的print时,首先被编码成utf-8,然后在送至终端显示,一切正常!
至此,你可能明白了该问题产生的原因,那么,这个问题该怎么解决呢?一般建议在调用print打印变量时,首先调用encode()函数将unicode类型的变量进行编码,转换成str类型的变量,代码3如下:
#coding=utf-8
import sys
print sys.getdefaultencoding()
a="测试"
b=u"测试"
print a
print b.encode('utf-8')
之后,程序运行正常,如下:

3.linux终端显示中文乱码
第1节中曾提到过:如果str类型的变量的编码方式和终端设置的编码方式不一致,在终端显示时就会出现中文乱码问题。笔者使用的终端的编码方式为utf-8,如下图:

如果将终端的编码方式改为GB2312,则中文就会出现乱码。因为b.encode('utf-8')的编码为utf-8,而终端的为GB2312,因此导致了乱码。

解决方法就是要保持终端编码和待显示的变量的编码方式的一致。
【原创】python中文编码问题深入分析(二):print打印中文异常及显示乱码问题分析与解决的更多相关文章
- 【原创】python中文编码问题深入分析(三):python2.7文件读写中文编码问题
		
上一篇文章介绍和分析了python2.7中使用print遇到的中文编码问题的原因和解决方案,本篇主要介绍一下python2.7中执行文件读写可能遇到的编码问题. 1.文件读取 假如我们读取一个文件,文 ...
 - python中文编码问题深入分析(一):字符编码基础
		
背景:笔者作为一名刚接触python语言的新手,在实际的项目中,遇到过一些中文编码问题,初次遇到这些问题的时候,刚开始显得有些手足无措,也不知从何查起.常言道:有问题,找度娘!当我打开www.baid ...
 - python简说(二十六)异常
		
# try:# res = 1 / 0# except ZeroDivisionError as e:# print('出错啦,除数不能为0',e) # l = list()# l.append(1) ...
 - pycharm打印出的汉字显示乱码
		
pycharm未配置时,默认配置为: 打印汉字时显示乱码 简单设置即可 这下以后就没有问题了.
 - Python+OpenCV图像处理(二)——打印图片属性、设置图片存储路径、电脑摄像头的调取和显示
		
一. 打印图片属性.设置图片存储路径 代码如下: #打印图片的属性.保存图片位置 import cv2 as cv import numpy as np #numpy是一个开源的Python科学计算库 ...
 - python自动化测试之mysql5.0版本数据库查询数据时出现乱码问题分析
		
1.确保数据库编码是utf8编码.若不是,请将my.ini的client,mysql,mysqld三个字段下面添加default-character-set = utf8,这样可以永久改变在新建数据库 ...
 - python在windows系统中打印中文乱码
		
转自:http://www.111cn.net/phper/python/58920.htm 中文乱码对于程序开发人员来讲不是什么怪事情了,今天我在使用python打印中文时就出现乱码了,下面我们一起 ...
 - Python使用print打印时,展示内容不换行
		
原理 Python的print()函数中参数end='' 默认为\n,所以会自动换行; 默认的print()函数: print(end='\n') 方案 Python 2: 在print语句的末尾加上 ...
 - Python学习4——print打印
		
print(): 在控制台输出变量的值: print打印完后换行: print(123) # 完整模式:print(123,end="\n") 希望打印完不换行: print(1 ...
 
随机推荐
- ios上 更改 状态栏(UIStatusBar)的颜色,你值得一看、收藏
			
IOS上 关于状态栏的相关设置(UIStatusBar) 知识普及 ios上状态栏 就是指的最上面的20像素高的部分 状态栏分前后两部分,要分清这两个概念,后面会用到: 前景部分:就是指的显示电池.时 ...
 - angular中ui calendar的一些使用心得
			
ui calendar是封装fullcalendar的一款angular指令插件 官方地址:http://angular-ui.github.io/ui-calendar/ fullcalendar ...
 - 在ubuntu上安装k-vim
			
在ubuntu 上安装k-vim 早就想好好改造一下自己使用的vim了!可惜各种配置都十分复杂,特别是涉及到C语言的语义补全,YouCompleteMe,总是出各种安装问题.今天有人推荐我使用k-vi ...
 - bzoj1468
			
1468: Tree Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1023 Solved: 532[Submit][Status][Discuss] ...
 - JS拖动技术--- 关于setCapture
			
<script type="text/javascript"> <!-- window.onload=function(){ objDiv = documen ...
 - 利用JS做到隐藏div和显示div
			
div的visibility可以控制div的显示和隐藏,但是隐藏后页面显示空白 style="visibility: none;" document.getElementById( ...
 - python访问sqlserver
			
#coding=utf-8 #!/usr/bin/env python#---------------------------------------------------------------- ...
 - Bootstrap Paginator分页插件+ajax 实现动态无刷新分页
			
之前做分页想过做淘宝的那个,但是因为是后台要求不高,就Bootstrap Paginator插件感觉还蛮容易上手,所以就选了它. Bootstrap Paginator分页插件下载地址: Downlo ...
 - oracle的位图索引和函数索引
			
1.位图索引 位图索引适用于性别.婚姻状态.行政区等只有几列固定值的类型列,身份证号等就不适合位图索引,位图索引适用于静态数据,频繁更新的字段不适用建立位图索引,因为更新会导致索引块区的变更,还会引起 ...
 - 一篇完整的FlexBox布局指南
			
一篇完整的FlexBox布局指南 转载请标注本文链接并附带以下信息: 译:Cydiacen 作者:CHRIS COYIER 原文:A Complete Guide to Flexbox 原文更新于 2 ...