在讨论python编码之前,我先了解了几种编码的由来。

一、编码类型

1、ascci码

ascci码由美国人发明,用1个字节(byte)存储英文和字符,前期用了128个,后来新加了其他欧洲国家的符号,128~255这一段。
256个字符,基本上就是键盘上的所有字符。

2、unicode

2个byte,65535。因为后来发现还有其他国家的语言,而256个字符太少。

3、utf-8

UTF-8是Unicode的实现方式之一。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则很简单,只有二条:

  • 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
  • 对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

下表总结了编码规则,字母x表示可用编码的位。

Unicode符号范围         |       UTF-8编码方式
(十六进制)                    |       (二进制)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

4、GBK

GBK全称《汉字内码扩展规范》(GBK即“国标)就是国家制定的标准。

其实GBK在就是将每个汉字对应一个数字编码,http://www.mytju.com/classCode/tools/encode_gb2312.asp 这个网址可以查看到具体的编码对应关系:

比如:中国  二字,对应的各种编码如下。

二、为什么要转码?

在python程序运行过程中,如果遇到编码不一致(就好像中国人和美国人在一起,如果语言不通的话,就无法沟通。),就需要进行转码。相当于需要有一个翻译。

在运行Python程序的过程中,会涉及到三个方面的编码:

  1. Python程序文件本身的编码(test.py文件的编码)--自身文件

  2. Python程序运行时环境的编码(比如securecrt,类似mysql客户端连接时的编码)--客户端
  3. Python程序读取外部文件的编码(引用外部文件的编码)--外部文件

下面对于以上三种情况为什么需要转码分别进行说明:

情况一(自身文件编码问题)

python2默认编码为ascii,如果我们写的代码里面有非ascii字符,比如中文字符,py程序就会不认识。

就相当于两个人都用普通话在沟通,其中某一个人突然蹦出一句家乡话,另外一个人突然就懵逼了,同样,python也懵逼了。

记得刚开始接触python时,就碰到了经典错误,然后网上各种找资料,后来照着网上前辈们的设置,也没有深究其原理。

经典错误范例:

#!/usr/bin/env python

print '你好 大鸟'

运行时会报错:

SyntaxError: Non-ASCII character '\xe4' in file t.py on line 4, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

错误原因:python2默认的编码为ascii,python3默认编码为utf-8,而文件里面包含了非ASCII字符,所以他肯定不认识,就报错了。

可以通过sys模块查看默认编码:

>>> sys.getdefaultencoding()
'ascii'

怎么解决?

针对情况一解决方法:(目的都是将默认编码修改成utf-8,这样,程序既可以认识ascii,又可以认识utf-8了)

解决方法一:
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
解决方法二:
#coding:utf8
解决方法三:
#-*- coding:utf-8 -*-

  

 

情况二(客户端编码问题) 

我们在使用mysql时,如果客户端设置为latin,而服务端为utf-8,查询内容有中文时,就会出现乱码。同样,我们在使用python时,secureCRT也是客户端,服务端就是我们连接的服务器。

范例:

1、客户端设置secureCRT编码为UTF-8

2、服务端测试

3、设置客户端为非utf-8时,就会出现乱码

结果如下:

而且从步骤2中也可以看出,python自动识别变量a='中国test'为utf-8的编码,如果客户端(secureCRT)和服务端(python)编码不一致时,就会出现乱码。

情况二解决办法:设置客户端的编码格式和服务端一致!

情况三:读取外部文件时,出现乱码

比较典型的就是:当我们从windows上编辑一个文件,上传到linux上时,会惊奇的发现^M符号。这个就是因为windows和linux的回车换行符不一致导致的,此时如果是python文件时,python也会报错。

我们在linux先查看时会有特殊符号:

这时,如果我们需要去掉^M,需要使用dos2unix工具转换一下,去掉windows上的格式。

三、编码怎么转换

unicode为桥梁,utf-8和gbk互转需要经过unicode这个翻译,不然他们二者是无法直接沟通。

操作范例:

1、查看默认编码,python遇到中文字符,会识别他是utf-8编码,chardet模块可以识别编码格式,但是也不是100%,下面他识别出myname为utf-8的概率为75%。

2、将utf-8转为unicode编码

utf-8转为unicode编码是,需要指定他本身是什么格式的编码,类似于加密。查看myname_unicode变量时,发现他是unicode编码格式了。

3、将unicode编码转为utf-8

具体转换操作如下:

例子:

>>> a=u'中国'  #unicode编码格式的字符串
>>> a_utf8=a.encode('utf-8') #将unicode转成utf-8编码格式
>>> a_utf8
'\xe4\xb8\xad\xe5\x9b\xbd'
>>> a_unicode=a_utf8.decode('utf-8') #从utf8编码格式转回unicode编码格式
>>> a_unicode
u'\u4e2d\u56fd'
>>> a
u'\u4e2d\u56fd'
>>>
>>> b_gbk=a_unicode.encode('gbk')  #将上面unicode格式的转成gbk编码格式
>>> b_gbk
'\xd6\xd0\xb9\xfa'
>>> b_unicode=b_gbk.decode('gbk') #转回unicode编码格式
>>> b_unicode #最后发现,a_unicode、b_unicode和原始的unicode编码的a都相等。
u'\u4e2d\u56fd'
>>> a_unicode
u'\u4e2d\u56fd'
>>> a
u'\u4e2d\u56fd'
>>>

a.encode(* *):将a 编码 为 * *编码格式的字符串或unicode对象

a.decode(* *):将a 解码 为 unicode编码格式的字符串或unicode对象

 另外:

Python将字符串格式的unicode编码转换成unicode编码,如:\u53eb\u6211,需要转换成中文时有两种方式

1.使用eval:

eval("u"+"\'"+unicodestr+"\'")

2.使用decode:

str1 = '\u4f60\u597d'
print str1.decode('unicode_escape')
你好

unicodestr.decode('unicode_escape')  # 将转义字符\u读取出来

四、参考文献和文件索引

1、汉字对应表:http://www.chi2ko.com/tool/CJK.htm

2、阮一峰的网站

彻底搞清楚python字符编码的更多相关文章

  1. 深入理解Python字符编码--转

    http://blog.51cto.com/9478652/2057896 不论你是有着多年经验的 Python 老司机还是刚入门 Python 不久,你一定遇到过UnicodeEncodeError ...

  2. 深入理解Python字符编码

    不论你是有着多年经验的 Python 老司机还是刚入门 Python 不久,你一定遇到过UnicodeEncodeError.UnicodeDecodeError 错误,每当遇到错误我们就拿着 enc ...

  3. python 字符编码练习

    通过下面的练习,加深对python字符编码的认识 # \x00 - \xff 256个字符 >>> a = range(256)>>> b = bytes(a) # ...

  4. Python字符编码讲解

    声明:本文参考 Python字符编码详解 在计算机中我们不管用什么语言和程序,最终数据在计算机中的都是字节码(也就是01形式)的形式存在的,如果 计算机直接把字节码显示在屏幕上,很明显一般人看不懂字节 ...

  5. Python字符编码详解,str,bytes

    什么是明文 “明文”是可以是文本,音乐,可以编码成mp3文件.明文可以是图像的,可以编码为gif.png或jpg文件.明文是电影的,可以编码成wmv文件.不一而足. 什么是编码?把明文变成计算机语言 ...

  6. Python字符编码补充

    字符编码: Python字符编码贯穿Python学习的始终,现在应用的是Python2中字符编码的问题是很多的. 这次是要彻底解决Python字符编码的问题!!! 1 字符编码的发展过程: 1 .AS ...

  7. python --- 字符编码学习小结(二)

    距离上一篇的python --- 字符编码学习小结(一)已经过去2年了,2年的时间里,确实也遇到了各种各样的字符编码问题,也能解决,但是每次都是把所有的方法都试一遍,然后终于正常.这种方法显然是不科学 ...

  8. 转1:Python字符编码详解

    Python27字符编码详解 声明 一 字符编码基础 1 抽象字符清单ACR 2 已编码字符集CCS 3 字符编码格式CEF 31 ASCII初创 311 ASCII 312 EASCII 32 MB ...

  9. 转2:Python字符编码详解

    1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有 ...

随机推荐

  1. 关于WSL(Windows上的Linux子系统)的简单介绍及安装

    WSL,Windows Subsystem for Linux,就是之前的Bash on [Ubuntu on] Windows(嗯,微软改名部KPI++),在wsl环境下我们可以运行一些Linux程 ...

  2. Windows下Git使用报错:warning:LF will be replaced by CRLF in ××××.××

    Windows下Git使用报错: warning:LF will be replaced by CRLF in ××××.××(文件名) The file will have its original ...

  3. [webpack] Webpack 别名

    存在这样一种情况,有时候项目中,存在一些 公共的组件,通常会抽取出来,放在一个统一的文件夹中. 然后大家就可以再 各个 模块里面 愉快的使用该 组件了.   但是也带来一个坑爹的问题 组件放在 com ...

  4. #003 React 组件 继承 自定义的组件

    主题:React组件 继承 自定义的 组件 一.需求说明 情况说明: 有A,B,C,D 四个组件,里面都有一些公用的逻辑,比如 设置数据,获取数据,有某些公用的的属性,不想在 每一个 组件里面写这些属 ...

  5. JDK/bin目录下的不同exe文件的用途

    新安装完JDk 大家是否发现安装目录的bin文件夹有很多exe文件 下面就为大家讲解不同exe文件的用途 javac:Java编译器,将Java源代码换成字节代 java:Java解释器,直接从类文件 ...

  6. Android 高级UI设计笔记23:Android 夜间模式之 两种常用方法(降低屏幕亮度+替换theme)

    1. 夜间模式 所谓的夜间模式,就是能够根据不同的设定,呈现不同风格的界面给用户,而且晚上看着不伤眼睛.特别是一些新闻类App实现夜间模式是非常人性化的,增强用户体验. 2. 我根据网上的资料 以及自 ...

  7. was集群下基于接口分布式架构和开发经验谈

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/luozhonghua2014/article/details/34084935    某b项目是我首 ...

  8. Windows7下配置JMeter安装环境

    JMeter配置安装 1.安装JDK环境  下载地址:http://www.Oracle.com/technetwork/Java/javase/downloads/jdk8-downloads-21 ...

  9. Spring整合MyBatis(二)Spring整合MyBatis

    摘要: 本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 了解了MyBatis的独立使用过程后,我们再看看它与Spring整合的 ...

  10. JAVA开发微信支付-公众号支付/微信浏览器支付(JSAPI)

    写这篇文章的目的有2个,一是自己的项目刚开发完微信支付功能,趁热回个炉温习一下,二也是帮助像我这样对微信支付不熟悉,反复看了多天文档还是一知半解,原理都没摸清,更不要说实现了.本以为网上的微信开发教程 ...