Python编码问题一直困扰了我许久,之前有过一些总结,但并不系统,比较凌乱。当然python2.x编码问题本身,便是剪不断理还乱。本篇将系统介绍python2.x编程中会遇到的一些编码问题,并给出解决方案。基于对编码问题的摸索了解,我也尝试写了一个编码转换模块Transcode,应该能解决绝大部分新手的疑难杂症。当然,python大神可以绕道而行,至于使用3.x的朋友,以后将会成文介绍。

python编程中会经常遇到操作系统编码、文件编码、控制台输入输出编码、网页编码、源代码编码、python编码,本文将会逐一介绍。首先我们来看看一些常见的编码情况:

print sys.getdefaultencoding() #系统默认编码

print sys.getfilesystemencoding() #文件系统编码

print locale.getdefaultlocale() #系统当前编码

print sys.stdin.encoding #终端输入编码

print sys.stdout.encoding #终端输出编码

将以上这段代码在windows与linux系统下分别运行,查看输出结果。

windows终端结果:

ascii

mbcs

('zh_CN', 'cp936')

cp936

cp936

Linux终端结果:

ascii

UTF-8

('zh_CN', 'UTF-8')

UTF-8

UTF-8

操作系统编码

操作系统默认编码可以通过sys.getdefaultencoding()函数获取,可以看到windows与linux下默认都为ascii编码,而我们知道ascii编码不支持中文。那么操作系统编码将在python程序的何处会被用到呢?何时又会引发血案?

触发异常点

经过测试,我发现当需要将unicode格式的字符串存入到文件时,python内部会默认将其先转换为Str格式的系统编码,然后再执行存入步骤。而在这过程中,容易引发ascii异常。

实例证明:

#! -*- coding:utf-8 -*-

a=u"中文"

f=open("test.txt","w")

f.write(a)

报错异常信息:UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-1……

说明:因为ascii不支持中文,而变量a为unicode格式的中文字符串,因此无法进行编码而引发异常。

解决方案

设置系统编码为utf-8或者gbk。

import sys

reload(sys)

sys.setdefaultencoding('gbk')

说明:在windows下将其设置为gbk,在linux在设置为utf-8.

终端编码

windows下终端指的是控制台,在控制台上输入输出有着其本身的编码格式,如windows控制台输入输出编码都为cp936。原谅我是第一次看到此编码,于是上网查了会,发现其实它就是常见的GBK编码;而linux终端的输入输出编码都为utf-8。如果我们编写的程序,不会再终端输入输出任何内容,则可以忽略此编码,如若不然终端编码将会非常重要。

乱码点

我们在终端执行python脚本时,经常会遇到输出中文乱码,而这往往是因为输出的字符串本身编码与控制台编码不一致。

实例证明:

#! -*- coding:utf-8 -*-

a="中文" #定义一个变量,默认为Str,utf-8编码

print a

print type(a)

windows控制台输出结果:

浣犲ソ

linux终端输出结果:

中文

造成这种差异的原因在于windows控制台为gbk编码,而变量a本身为utf-8编码。

解决方案

#! -*- coding:utf-8 -*-

a='你好'

b=a.decode("utf-8").encode("gbk")

print b

将变量a从utf-8编码转换为gbk编码。

python编码

python2.x从外部获取的内容都是string编码,其内部分为String编码与Unicode编码,而String编码又分为UTF-8,GBK,GB2312等等。因此为了避免不同编码造成的报错,python内部最好都转化为unicode编码,在输出时再转化为str编码 。可以用encode()/decode()函数,将string与unicode编码互换。

触发异常点

基本在于python内部变量编码与控制台编码,或者其他编码相结合时触发。

实例证明:

#! -*- coding:utf-8 -*-

a="中文" #定义一个变量,默认为str,utf-8编码

print a

print type(a)

运行结果:

浣犲ソ

说明:windows下控制台输入输出都是gbk编码格式,而代码中定义的变量a为str,utf-8格式,所以会出现乱码。如果想创建一个unicode编码字符串的变量,则可以a=u”123”,在双引号前面加上一个u,表示a为unicode编码。

解决方案

#! -*- coding:utf-8 -*-

a='你好'

print a.decode("utf-8").encode("gbk")

说明:首先我们定义的变量a是str格式,编码为utf-8的字符串,我们要将之转化为str格式,GBK编码的字符串。在python内部无法直接转化,需要借助decod()与encode()函数。decode()函数先将str格式的字符串a转化为unicode,再将unicode编码为str格式GBK。而在Unix系统下,不存在这个问题,因为都是utf-8编码,不会存在乱码。print语句默认会将unicode编码的字符串,encode为相应系统的str编码并输出(windows下为gbk,unix下为utf-8),因此不用担心print unicode编码字符串会报错。

源代码编码

源代码编码指的是python程序本身的编码,默认为ascii。

触发异常点

python程序本身要被解释器解析执行,需要先被转化为二进制代码。而在这过程中容易引发异常,原因同样是ascii不支持中文,因此当python程序中出现中文时,哪怕是注释,也会引发ascii异常。

实例证明:

print "中文" #中文注释

报错:SyntaxError: Non-ASCII character ‘\xe7’……

解决方案

#! -*- coding:utf-8 -*-

python程序开头加上这句代码,指定python源代码编码格式为utf-8。

文件编码

文件编码指的是,python程序从文件中获取的内容的编码格式。可以用sys.getfilesystemencoding()函数获取,windows下为mbcs,linux下为utf-8。至于mbcs,是一种多字节编码(没搞很明白)。

触发异常点(读取文件内容)

当python程序从文件中获取内容,并输出时,容易触发异常。

实例证明:

#! -*- coding:utf-8 -*-

f=open("test.txt","r")

content=f.read()

print type(content)

print content

运行结果:

你好

可以看到windows下,从文件中读取的编码格式为Str,GBK格式(因为控制台输出没有中文乱码);而在Unix下为Str,Utf-8格式。从输出内容来说,并没有触发异常,然而当这些内容与python程序自身内容相结合时,容易触发异常。

解决方案

在windows下,最好将文件内容转为unicode,可以使用codecs:

f=codecs.open("test.txt", encoding='gbk').read()

将格式为gbk的文件内容转化为unicode格式,当然也可以直接使用open(“”,”r”).read().decode(“gbk”)

触发异常点(写入文件内容)

参考操作系统编码触发异常点,即将中文unicode字符写入文件时,容易触发异常。

解决方案

参考操作系统编码解决方案,或者手动将unicode编码转换为str编码。

实例证明:

#! -*- coding:utf-8 -*-

a=u"中文" #a为unicode格式编码

f=open("test.txt","w")

f.write(a.encode("gbk"))

当然如果变量a本身就是Str则不会报错,只是utf-8编码的内容写入windows文件中,显示会乱码。

网页编码

网页编码,通常在写爬虫的时候经常遇到,再结合系统编码,python编码,文件编码,往往会搞得一团乱。在程序中我们应该分别处理这些编码,在python内部全部转化为unicode。那么网页编码又有哪些格式呢?

常见格式:utf-8,gbk,gb2312

触发异常点

还是在于从网页中获取的源码编码与终端编码,甚至python内部编码不一致的情况。

实例证明:

#!coding=utf-8

import urllib2

body=urllib2.urlopen('http://thief.one').read()

print type(body)

print body

运行结果:

body中文显示乱码

说明:这个网站的编码是utf-8,而且python从网页上爬取的内容都为Str格式,在windows控制台下输出会乱码。

解决方案

依照之前做法,先将其转化为unicode。而相应的正则也可以为unicode编码,如:res=r’’+u”新成员”。可以通过chardet模块判断网页编码类型,返回的是一个带概率的字典。

编码判断

判断字符串编码

isinstance(obj, (str, unicode))

返回True或者False

判断网页编码

import chardet

import urllib2

body=urllib2.urlopen("http://thief.one").read()

chardet.detect(body)

判断编码格式,会有百分比,一般用来判断网页编码比较好。

判断系统编码

print sys.getdefaultencoding() #系统默认编码

print sys.getfilesystemencoding() #文件系统编码

print locale.getdefaultlocale() #系统当前编码

print sys.stdin.encoding #终端输入编码

print sys.stdout.encoding #终端输出编码

python2.x编码建议请尽量在Linux系统上编程,综上我们可以知道linux下较windows,编码问题良好很多。

python代码内部请全部使用unicode编码,在获取外部内容时,先decode为unicode,向外输出时再encode为Str

在定义变量或者正则时,也定义unicode字符,如a=u”中文”;res=r””+u”正则”。

其他疑难杂症

实例一:

a="\\u8fdd\\u6cd5\\u8fdd\\u89c4"

print a

变量a的内容本身为unicode编码,怎么正常显示输入?

解决方案:

a="\\u8fdd\\u6cd5\\u8fdd\\u89c4" # unicode转化为中文

b=a.decode('unicode-escape')

print b

如果阅读完本章,增加了您对python编码问题的认识,那我会感到欣慰,如有python编码上的问题可以在下方留言。

如果阅读完本章,您仍然不知如何解决python乱码问题,没关系,请继续移步阅读Transcode解决python编码问题

为了能够让您重视,我不得不再次重申:解决python2.x编码问题的关键,在于要明白无论从哪里来的内容,在python内部流通时,都应该先转换为unicode。(python3.x在这方面做了改进,并取得了很好的效果)技术的探索,就好像编织故事一般,其乐趣在于偶尔能够讲述给别人听,并获得一些赞同!

python2默认编码_解决Python2.x编码之殇相关推荐

  1. python中文转到ascii码_解决Python2中文ascii编码的方法

    在YiiChina签到的时候,经常会看到有人在说说里面发群主是最帅的,yii 是 PHP 最好的框架,没有之一,就想到使用一言,在每天签到的时候也发一句话 同时使用方糖将内容推送到微信,防止有什么不对 ...

  2. python读excel乱码_解决Python2.7读写文件中的中文乱码问题

    Python2.7对于中文编码的问题处理的并不好,这几天在爬数据的时候经常会遇到中文的编码问题.但是本人对编码原理不了解,也没时间深究其中的原理.在此仅从应用的角度做一下总结, 1.设置默认编码 在P ...

  3. python2安装包_解决win10下python2和python3共存问题

    前言 本文讨论在win10下解决python2和python3共存问题. 一.基础知识 1.python的安装: 分别下载Python2和Python3安装包,然后依次点击安装即可,安装包地址如下: ...

  4. 北大青鸟消防设备类型编码_探测器该如何编码?即报警区域、探测区域的真正用途...

    <火灾自动报警系统设计规范> GB 50116-2013中说到 报警区域是将火灾自动报警系统的警戒范围按防火分区或楼层等划分的单元. 报警区域应根据防火分区或楼层划分:可将一个防火分区或一 ...

  5. python绘图设置标题出现乱码_解决python2 绘图title,xlabel,ylabel出现中文乱码的问题...

    Python绘图如何显示中文标题一个懂得以幽默态度面对自己缺点并将缺点变成自己专属的特色-这才是真正乐观勇敢的人. 采用matplotlib作图时默认设置下是无法显示中文的,例如编写如下python脚 ...

  6. linux windows文件 编码_解决Linux与Windows文件显示乱码的问题

    重点:如果windows 下和虚拟机共享文件,先将文件移到其他位置使用notepad++ 改变编码模式为UTF-8,然后复制到共享目录,然后用编辑器打开中文就不是乱码了. 问题: 在Windows下用 ...

  7. java 判断zip文件编码_如何使用UTF-8编码打开java程序生成的zip文件

    我们的产品有一个导出功能,它使用ZipOutputStream压缩目录;但是,当您尝试压缩包含具有中文或日文字符的文件名的目录时,导出将无法正常工作.由于某种原因,压缩文件中的新文件的命名方式不同.以 ...

  8. 电子白板 矢量 编码_当涉及白板编码采访时,请记住准备

    电子白板 矢量 编码 by Andy Tiffany 通过安迪·蒂芙尼(Andy Tiffany) 当涉及白板编码采访时,请记住准备 (When it comes to whiteboard codi ...

  9. 程序员 rs编码_为什么声明性编码使您成为更好的程序员

    程序员 rs编码 在许多情况下,具有功能组成的声明式解决方案提供了优于传统命令式代码的出色代码指标. 阅读本文并了解如何使用具有功能组成的声明性代码成为一名更好的程序员. 在本文中,我们将仔细研究三个 ...

最新文章

  1. 【转】 Android快速开发系列 10个常用工具类 -- 不错
  2. 【小白学习keras教程】十一、Keras中文本处理Text preprocessing
  3. Django从理论到实战(part41)--WSGIRequest对象
  4. python多进程与多线程实验
  5. MathType插入带序号公式的两种方法
  6. datavideo切换台说明书_巴掌大三轴稳定器,稳过微云台,试试飞宇VLOGPocket2
  7. 函数调用关系图如何画_彩铅画入门植物教程 | 如何用彩铅画一株多肉?多肉彩铅画教程步骤图详细...
  8. Linux做施压机的最大线程数,关于性能测试的几个要点
  9. 我妈妈要求一台Linux计算机
  10. Hive列合并与元素搜集
  11. 360驱动大师 2.0.0.1750 去广告去多余图标优化版(安装版 + 单文件版 + 网卡版)
  12. 谷歌方法 pdf txt azw3 epub mobi 百度云盘网盘下载
  13. livereload
  14. 中断python快捷键_python的快捷键
  15. Rayson API 框架分析系列之5: NIO实现原理
  16. svn conflict linux,解决svn update 产生Node remains in conflict的问题
  17. GD32W515实现NES模拟器
  18. 图片怎样编辑文字?分享三个图片编辑修改文字的方法
  19. 数据可视化分析平台开源方案集锦
  20. Swift 语言概览

热门文章

  1. 提交客户端证书_MQTT X v1.3.3 正式发布 - 跨平台 MQTT 5.0 桌面测试客户端
  2. eclipse打包成jar_Spring Boot 打包成的可执行 jar ,为什么不能被其他项目依赖?
  3. 不想跑数了,数据分析师的前途在哪里?
  4. 程序员的日常竟然是这样,真的是又心疼又好笑······
  5. 刷新纪录 | 74.7 秒训练完 ImageNet!2048 GPU 暴力出奇迹
  6. python3.7如何使用enum_Python3.4 枚举类型的使用
  7. android 6.0权限封装,Android6.0------权限申请管理(单个权限和多个权限申请)
  8. 打造vim的python编辑器
  9. D3js(四):箭头arrow
  10. leetcode-67-二进制求和