一.前言

在学习python初期,常常会对运行文件出现的各种"codec"报错摸不着头脑有没有?

对各种编码方式的区别和适用的情况混淆有没有?

对python2,python3 编码区别傻傻分不清有没有?

编码转换出错,页面出现乱码等等问题分析不清楚,就很容易掉坑里。。。

本文通过深入理解字符串存储,显示,和传输时候使用不同编码方式的原因,对python编码有关的问题来进一步加深理解。

二.什么是字符集?

字符集是一个抽象的概念,它与编码无关,比如英文字符,数字标点,中文字符,这些都可以称之为字符集

三.什么是编码?

编码的本质其实就是翻译,举个几个例子:

两个说普通话的中国人进行交流时,是不需要编码的,一个人说「你好」,另一个就能直接听明白意思,反之亦然。

一个中国人和美国人交流时,就需要多一个中文到英文、和英文到中文的翻译过程,才能实现双向交流。

一个人类和计算机交流时,也是一样的道理,大家都知道计算机只认识二进制0和1,因此必须把人类语言转为二进制,才能把信息传递给计算机,这个过程叫做编码(encoding),反之则称为解码(decoding)。

四. 怎么编码?

ASCII

美国信息交换标准代码(American Standard Code for Information Interchange,简称ASCII)是一种用于信息交换的美国标准代码,它的作用是给英文字母、数字、标点、字符转换成计算机能识别的二进制数规定了一个大家都认可并遵守的标准。(因为是美国人设计的,所以只有常用英文字符)

ASCII表太小了,最多只能编码128个字符,但人类语言又那么多,显然无法满足需求,于是世界各地的人们就分别设计了符合自己语言需求的映射表。

GB2312编码

适用于汉字处理、汉字通信等系统之间的信息交换。

GBK编码

是汉字编码标准之一,是在 GB2312-80 标准基础上的内码扩展规范,使用了双字节编码。(GBK包含GB2312的同时,又         增加了近20000个新的汉字,有生僻字。)

ANSI(扩展的ASCII编码)

与你使用的windows操作系统的语言有关系的,向windows 7 简体中文版就是GBK(用一个字节表示英文,用两个字节表         示一个中文)。

Big5

繁体字(香港台湾)

以上各种编码方式,在自己的地区使用时是没有问题的,但是一旦进行国际交流,由于映射规则各不相同,就会导致混乱。

于是人们设计了一个很大的映射表——

Unicode编码

这是一种世界上所有字符的编码

,但是它没有规定的存储方式。

范围:0x000000-0x10FFFF(十六进制),有110多万

现代操作系统和大多数编程语言都直接支持Unicode。

Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。

比如“中”的unicode编码为十六进制0x4E2D,需要用两个字节来表示,有些字符可能需要3个甚至4个字节来表示,

如果都采用定长编码,就会造成存储空间的极大浪费,因为我们知道英文字符只需要一个字节就能表示,于是便有了对unicode的不同实现方案,目前最广泛使用的就是utf-8

UTF-8编码

是 Unicode Transformation Format - 8 bit 的缩写, UTF-8 是 Unicode 的一种实现方式。它是可变长的编码方式,可以使用 1~4 个字节表示一个字符,可根据不同的符号而变化字节长度。

五.几种主要编码的比较

UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分

大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作

UTF-8,UTF-16和UTF-32的一些区别

UTF8:UTF编码方式的设计初衷主要就是节省空间,UTF-8因为兼容ASCII,可以使用一个字节表示英语世界常用字符,比较省空间和带宽。UTF-8是变长的字符串。主流使用UTF-8编码,兼顾空间和功能处理的便捷性。

UTF16:因为使用两个字节为单位,所以分大尾和小尾,用的很少。

UTF32:表示任何字符都是4字节,缺点太占空间,基本不使用。

六. Python的字符串类型:

➢ Unicode的字符串:默认类型,或者被字节字符串 decode 后的类型

➢ 字节字符串:bytes类型,被 encode 后的字符串类型

Python3 内部的字符串一般都是Unicode编码。

1. 代码中字符串的默认是unicode。

2. 所以要做一些编码转换通常是要将Unicode转换为对应得字节字符串,即从Unicode编码(encode)成另一种编码。

unicode→encode(“utf-8”)

方法一:

>>> s="abc"

>>> type(s)

>>>

s="abc".encode("utf-8")

>>> type(s)

方法二:

>>>

s=b"abc"

>>> type(s)

>>> s=b"abc"

>>> s=b"光荣之路"  #只适用于英文

File "", line 1

SyntaxError: bytes can only contain ASCII literal characters

3. decode 的作用是将其他编码的字符串转换成 Unicode 编码

>>> type(s.decode("utf-8"))

六. 字符类型转换:

用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里(decode),编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件(encode)

总结:

需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码(bytes类型)。

浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器

很多网页的源码上会有类似的信息,表示该网页正是用的UTF-8编码

Python中字符转换的过程:

总结:

encode

:编码  str --->bytes

decode

:解码  bytes --->str

解码与编码方式必须一致,不然会报错。

七.常见问题:

1.为什么页面有乱码?

没有解码为unicode

显示(

页面上需要看见的内容,都是通过解码的。)

你的bytes

类型编码在当前控制台不支持。

控制台:如果收到了一个utf-8 bytes类型,它会自动地用控制台的默认编码去decode来获取unicode来显示。如果默认的编码是utf-8,这个解码肯定没问题。如果默认是gbk,解码肯定就失败。编码和解码方式必须一样。

2.python中:encode和encoding有什么区别?

1)encode是一个方法:字符串才能用的。比如:”hello”.encode(“UTF-8”)

2)encoding是个参数:1 open的时候读写文件的时候用,2 在python文件的第一行去用。

比如:#encoding=UTF-8

3. 为什么文件保存为ansi编码(gbk),文件里只写了一句:print("越努力,越幸运!"),在控制台执行cc.py的时候报错了,报错信息如下,请问是什么问题导致的?应该怎么修改?

报错信息:

D:\phpStudy>python cc.py

File "cc.py", line 1

SyntaxError: Non-UTF-8 code starting with '\xa3' in file cc.py on line 1, but no encoding declared; see http://python.or

g/dev/peps/pep-0263/ for details

思路:

1 新建cc.py,用的ansi编码(gbk编码)保存的

2 文件的存储内容是gbk编码,python编译器要放到内存里面执行这个代码,这个时候需要的是bytes类型?还是unicode类型?

内存中使用unicode类型

3 因为文件的内容是bytes不能直接当做unicode放到内存中给编译器使用,所以必须解码,下一个解码我要用什么编码去解码呢?

得出答案:

如果你没有设定编码类型,那么python3默认用的是utf8来解码。

文件中是gbk编码,你用utf-8去解码,只能回失败

解决方法两种:

文件另存为utf-8编码,存储的编码和默认decode的编码就一致了,所以就没问题了

在python文件第一行加上#encoding=GBK(相当于修改python的默认解码的字符集,从utf8改为gbk解码,就可以解决)

注意:如果python文件不加encoding参数,那么默认等于#encoding=UTF-8

总结:

你的程序如果使用UTF-8编码保存,则文件的第一行写上(也可不写)#encoding=UTF-8。

你的程序如果使用GBK编码保存(即ANSI),则文件的第一行必须写上#encoding=GBK。

pycharm所有的文件默认保存的字符集都是UTF-8,可以写#encoding=UTF-8也可以不写,默认会加一个#encoding=UTF-8

4.如何验证字符转换是否成功?用chardet(只用于验证bytes)

>>> import chardet

>>> s="光荣之路自动化测试培训".encode("gbk")

>>> chardet.detect(s)

{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}

>>> s="光荣之路自动化测试培训".encode("gbk").decode("gbk")

>>> chardet.detect(s)  #

只用于验证bytes

Traceback (most recent call last):

File "", line 1, in

File "D:\phpStudy\lib\site-packages\chardet\__init__.py", line 34, in detect

'{0}'.format(type(byte_str)))

TypeError: Expected object of type bytes or bytearray, got:

>>> s="光榮之路在線教學".encode("utf-8")

>>> chardet.detect(s)

{'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}

>>> s="光榮之路在線教學".encode("gbk")

>>> chardet.detect(s)

{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}

>>> s="光榮之路在線教學".encode("ascii")

#

编码方式要包含字符集

Traceback (most recent call last):

File "", line 1, in

UnicodeEncodeError: '

ascii' codec can't encode characters in position 0-7: ordinal not in range(128)

5.Python2和Python3区别?

python2

python3

s="光荣之路"

类型:str

默认的编码:gbk(utf-8)---->Python3的bytes

类型:str

默认的编码:unicode--------->python2的s.decode后的内容

想获得unicode、bytes类型

s.decode("gbk")   类型:unicode  --------->

Python3的str类型

s.encode("gbk") 类型:bytes   ----------->

python2的str类型

打印 "hello world!"

print "hello world!"

print("hello")

文件

fp = open("xxx",w)

fp.write(s)   ----->s是带有编码信息的,文件变为了gbk编码的类型

fp = open("xxx",'w',

encoding="utf-8")

fp.write(s)   ----->

s

是不带有编码信息的,文件存什么编码,需要用encoding参数指定

python中gbk字符原因报错_深入理解Python中的字符和编码,结合,了解,与相关推荐

  1. python中gbk字符原因报错_不想再被鄙视?那就看进来! 一文搞懂 Python 2 字符编码...

    原标题:不想再被鄙视?那就看进来! 一文搞懂 Python 2 字符编码 程序员都自视清高,觉得自己是创造者,经常鄙视不太懂技术的产品或者QA.可悲的是,程序员之间也相互鄙视,程序员的鄙视链流传甚广, ...

  2. 中props使用this报错_为什么在静态方法中不能使用this

    看到这个标题的读者,在你们的心里多多少少都有自己的答案,下面说一下我的答案. 在JVM的运行时数据区中有个虚拟机栈(或Java栈),在它的里面是由栈帧'叠加'而成. 栈帧由局部变量表,操作数栈,动态连 ...

  3. python创建excel文件报错_[转]用Python读写Excel文件

    大部分Windows环境的开发人员都会选择Microsoft Excel API.实际上不仅仅是Python,几乎各种语言都有相应的方法使用它,因为核心的逻辑完全是由Microsft Excel自身提 ...

  4. python 相对路径报错_小白学 Python(18):基础文件操作

    人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...

  5. ecplice中class.forname一直报错_英雄联盟LOL闪退,弹出吉格斯报错BUGSPLAT

    不少玩家进入游戏对局之前就会弹出吉格斯报错,或者游戏中途出现报错等情况,网上说的办法很多,什么分辨率设置不对,提高虚拟内存,卸载一些不用软件等,都是有用的办法.弹窗下面有三个可点击,左边是上传错误日志 ...

  6. python的read函数调用报错_从零开始学Python(七):文件存储I/O流和异常捕捉

    这两天在搞小程序开发,耽搁了一下更新的进度,今天补上.一个完整的前端程序肯定离不开数据存储和网络两个模块,今天我们就先来讲讲python中的一种常见数据存储:文件存储!~! 文件存储(I/O操作) 何 ...

  7. python安装selenium报错_新手用Python运行selenium的常见问题

    1.更换Python版本 打开pycharm,点击 file--setting--project项目名--project Interpreter,点击右侧的设置,如下图 选择新Python版本的安装路 ...

  8. pythonif语句的冒号总是报错_干货:python入门if语句及其列表操作

    本教程使用的课本是<Python编程:从入门到实践>,作者:[美] Eric Matthes 本节学习代码中针对不同情况进行分别处理的方法,关键字是if.学完这节,从理论上讲,你就可以编写 ...

  9. 中引入文件报错_关于前端开发中的模块化

    前端开发离不开模块化,与模块化有关的关键字有以下几个: require/module.exports export/import define/require/exprots define/seajs ...

最新文章

  1. ubuntu查看文件和文件夹大小
  2. jquery --- 收缩兄弟元素
  3. 闲话WPF之十八(WPF中的资源 [4] )
  4. 东北林大计算机考研难吗,北京林业大学考研难吗?一般要什么水平才可以进入?...
  5. Zabbix安装和使用配置小结
  6. 涉密计算机多用户审批表,涉密计算机及信息系统安全策略
  7. 开发流程与管理--华为硬件开发
  8. jetbrains DataGrip 1.0注册破解方法
  9. 利用python计算圆球的体积_python计算圆周长、面积、球体体积并画出圆
  10. Win10资源管理器CPU持续占用20%解决方法
  11. ICWPT 2022 | 从技术突破到生态构建,小米坚持做充电领域的拓荒者和领先者
  12. python 古典密码第一弹(凯撒密码,Playfair密码,维吉尼亚密码)
  13. 游戏数据库版本更新神器Flyway
  14. 马云的SNS梦美好却残酷
  15. 【19调剂】东北林业大学森林工程邢艳秋老师调剂信息
  16. java中向上的尖括号是什么,什么lt; Tgt; (尖括号)在Java中是什么意思?
  17. k米评分容易得高分的歌_福州这家全新亮相的K歌王国,“舞台灯”都给你搭好了,简直酷到没朋友!...
  18. ln火线零线_插座ln哪个是火线零线 插座怎么买
  19. 1_3.数据交换技术*
  20. php实现实时刷新的股票,js实现股票实时刷新数据案例

热门文章

  1. MYSQL数据库的基本操作八(存储函数)
  2. python求打几场比赛-用python实行羽毛球比赛规则。
  3. xp系统启动数据库服务器,xp系统如何启用数据库服务器
  4. 安卓13:Android Studio Button组件默认样式为蓝紫色,无法更改
  5. java中dvd管理系统_一个DVD管理系统
  6. 详解CSS设置默认字体样式
  7. 用1元5角钱人名币兑换5分、2分和1分的硬币(每一种都要有)共一百枚,问共有几种兑换方案?并输出每种方案。
  8. DUMeter图形直观显示网络流量的监视器
  9. opencv处理图片批量添加噪声、以及光照、黑暗处理
  10. oppo小游戏接入代码