在学习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打印中文异常及显示乱码问题分析与解决的更多相关文章

  1. 【原创】python中文编码问题深入分析(三):python2.7文件读写中文编码问题

    上一篇文章介绍和分析了python2.7中使用print遇到的中文编码问题的原因和解决方案,本篇主要介绍一下python2.7中执行文件读写可能遇到的编码问题. 1.文件读取 假如我们读取一个文件,文 ...

  2. python中文编码问题深入分析(一):字符编码基础

    背景:笔者作为一名刚接触python语言的新手,在实际的项目中,遇到过一些中文编码问题,初次遇到这些问题的时候,刚开始显得有些手足无措,也不知从何查起.常言道:有问题,找度娘!当我打开www.baid ...

  3. python简说(二十六)异常

    # try:# res = 1 / 0# except ZeroDivisionError as e:# print('出错啦,除数不能为0',e) # l = list()# l.append(1) ...

  4. pycharm打印出的汉字显示乱码

    pycharm未配置时,默认配置为: 打印汉字时显示乱码 简单设置即可 这下以后就没有问题了.

  5. Python+OpenCV图像处理(二)——打印图片属性、设置图片存储路径、电脑摄像头的调取和显示

    一. 打印图片属性.设置图片存储路径 代码如下: #打印图片的属性.保存图片位置 import cv2 as cv import numpy as np #numpy是一个开源的Python科学计算库 ...

  6. python自动化测试之mysql5.0版本数据库查询数据时出现乱码问题分析

    1.确保数据库编码是utf8编码.若不是,请将my.ini的client,mysql,mysqld三个字段下面添加default-character-set = utf8,这样可以永久改变在新建数据库 ...

  7. python在windows系统中打印中文乱码

    转自:http://www.111cn.net/phper/python/58920.htm 中文乱码对于程序开发人员来讲不是什么怪事情了,今天我在使用python打印中文时就出现乱码了,下面我们一起 ...

  8. Python使用print打印时,展示内容不换行

    原理 Python的print()函数中参数end='' 默认为\n,所以会自动换行; 默认的print()函数: print(end='\n') 方案 Python 2: 在print语句的末尾加上 ...

  9. Python学习4——print打印

    print():  在控制台输出变量的值: print打印完后换行: print(123) # 完整模式:print(123,end="\n") 希望打印完不换行: print(1 ...

随机推荐

  1. UVA 10518 How Many Calls?

    题意:一个递推式第n项%b是多少. 递推式: 构造矩阵: #include<cstdio> #include<cstring> #include<cmath> #i ...

  2. SpringJDBC学习之路(1)

    本人从事java开发也有一段时间了,项目开发也有好几个.但感觉所有写的代码无非就是搬数据取数据.service层写的逻辑多一点,最近做的一个项目整个项目的结构以及层次发现代码过于臃肿冗余.同样一个方法 ...

  3. JDBC操作数据时中文乱码

    /** * DB地址 */ private static final String DB_URL="jdbc:mysql://localhost:3306/db_book?useUnicod ...

  4. uos事件控制块与任务同步

    Ucos为了任务之间的通讯定义了信号量,互斥性信号量,消息对象 消息队列等结构以及api,为了统一的管理这些同步,定义了一个结构叫做时间控制块OS_EVENT,如下 typedef struct os ...

  5. IOS 股票K线图、分时图

    IOS 股票K线图.分时图,网上开源项目很少,质量也是参差不齐:偶尔搜索到看似有希望的文章,点进去,还是个标题党:深受毒害.经过一段时间的探索,终于在开源基础上完成了自己的股票K线图.分时图: 先放出 ...

  6. tp框架命名空间

    命名空间:相当于虚拟的目录在tp里面主要为了实现自动加载类 TP框架下有一个初始命名空间(相当于根目录)初始命名空间:ThinkPHP\Library 在初始命名空间下又包含很多根命名空间这些根命名空 ...

  7. mongodb学习(二)分级查询数组中的值

    (PS: 标题有点不妥当...) 大概是这样...数据结构如下: 需要模糊查询title的值... mongodb中操作语句: 主要是注意这里urlElements不需要加[0]...我开始的时候写成 ...

  8. IOS开发-UI学习-NSMutableAttributedString(带属性的字符串)的使用

    带属性的字符串: NSString *aa = @"hellochinaIloveYou!"; NSMutableAttributedString *mas = [[NSMutab ...

  9. UVa 10299 - Relatives

    题目大意:Euler's Totient的应用. 几乎和UVa 10179 - Irreducable Basic Fractions一样,于是偷了个懒,直接用10179题的代码,结果WA了,感觉一样 ...

  10. 主流IOC框架测验(.NET)

    上一篇中,我简单介绍了下Autofac的使用,有人希望能有个性能上的测试,考虑到有那么多的IOC框架,而主流的有:Castle Windsor.微软企业库中的Unity.Spring.NET.Stru ...