在初次编写代码的过程中,由于不太了解编码形式,习惯性输入中文,得到的结果便是乱码、无法执行,经常抛出编码转换的异常。

常用的编码器:

ASCII

八位的字节一共可以组合出256(2的8次方)种不同的状态。

当时世界上所有的计算机都用同样的ASCII方案来保存英文文字。

GB2312

GB2312前身:扩展字符集

非英语的国家,他们的字母里有许多是ASCII里没有的,他们采用 127号之后的空位来表示这些新的字母、符号,还加入了很多画表格时需要用的横线、竖线、交叉等形状,一直把序号编到了最后一个状态255。从128 到255这一页的字符集被称”扩展字符集“。

中国人们得到计算机时,已经没有可以利用的字节状态来表示汉字,况且常用汉字太多了。于是完善了“扩展字符集”。

GB2312 是对 ASCII 的中文扩展。GB2312 规则:

1、一个小于127的字符称为半角”字符,意义与原来相同

2、两个大于127的字符连在一起时,就表示一个汉字

3、统统重新编了两个字节长的编码,就是常说的”全角”字符:高字节(从0xA1用到 0xF7)、数学符号、罗马希腊的字母、日文的假名们、ASCII 里面本来就有的数字、标点、字母

GBK——民族文化在计算机中记载的开始

GBK 包括了 GB2312 的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。

只要第一个字节是大于127就固定表示这是一个汉字,不管后面跟的是不是扩展字符集里的内容。

后来少数民族也要用电脑了,于是我们再扩展,GBK 扩成了 GB18030。

中国的程序员们看到这一系列汉字编码的标准通称他们叫做 “DBCS“(Double Byte Charecter Set 双字节字符集)。

DBCS最大的特点:两字节长的汉字字符和一字节长的英文字符并存于同一套编码方案里。

因此他们写的程序为了支持中处理,必须要注意字串里的每一个字节的值,如果这个值是大于127的,那么就认为一个双字节字符集里的字符出现了,一个汉字算两个英文字符。

UNICODE——承载地球上所有的文化

“Universal Multiple-Octet Coded Character Set”,简称 UCS, 俗称 “unicode“。包括了地球上所有文化、所有字母和符号的编码。

unicode 保持其原编码不变,只是将其长度由原来的8位扩展为16位,而其他文化和语言的字符则全部重新统一编码。

无论是半角的英文字母,还是全角的汉字,它们都是统一的”一个字符“!一个字符就是两个字节,“字节”是一个8位的物理存储单元,而“字符”则是一个文化相关的符号。

UTF-8——显示全世界上所有文化的字符

UTF-8是互联网上使用最广泛的一种 unicode 的实现方式

UTF-8 最大的一个特点:它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度,

当字符在 ASCII 码的范围时,就用一个字节表示,保留了 ASCII 字符一个字节的编码作为它的一部分,注意的是 unicode 一个中文字符占2个字节,而UTF-8一个中文字符占3个字节)。

接下来我们来比较一下unicode、latin-1、ASCII编码方式的兼容性问题:

首先,非ASCII字符无法使用ASCII编码转换成字节字符串

s = 'π排球の'
b = s.encode('ascii')Traceback (most recent call last):File "E:/12homework/12homework.py", line 2, in <module>b = s.encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3:ordinal not in range(128)

其次,Latin-1和unicode编码方式不兼容。

例如,重音字符会在latin-1字符集和unicode字符集中同时存在,但是通过latin-1和unicode编码方式编出来的字节流是不一样的,注意,虽然unicode字符集是包含了latin-1字符集,但是不代表utf-8编码方式兼容latin-1编码方式。因为unicode字符集中除了ascii字符集外,都是采用多字节的编码方式,而latin-1一律采用单字节的方式

s = 'Äè'
print(s.encode('utf-8'))
print(s.encode('latin-1'))b'\xc3\x84\xc3\xa8'
b'\xc4\xe8'

只有ascii字符集中的字符,三种编码方式得到的结果才完全一致。对unicode进行编码的时候,针对常规的7位ASCII文本,由于utf-8以及latin-1编码方式都是兼容ASCII的,所以结果都是一样的。

s = 'abc'
print(s.encode('utf-8'))
print(s.encode('latin-1'))
print(s.encode('ascii'))b'abc'
b'abc'
b'abc'

案例分析

源码文件的编码格式为utf-8,但是window的本地默认编码是gbk,所以在控制台直接打印utf-8的字符串当然是乱码了!

解决方法:

1、print mystr.decode('utf-8').encode('gbk')
2、比较通用的方法:

import sys
type = sys.getfilesystemencoding()
print mystr.decode('utf-8').encode(type)

1. Python中列表或字典输出乱码的解决方法

问题: Python中的列表(list)或字典包含中文字符串,直接使用print会出现以下的结果:

#打印字典
dict = {'name': '张三'}
print dict
>>>{'name': '\xe5\xbc\xa0\xe4\xb8\x89'}#打印列表
list = [{'name': '张三'}]
print list
>>>[{'name': '\xe5\xbc\xa0\xe4\xb8\x89'}]

解决方案:
使用以下方法进行输出:

import json#打印字典
dict = {'name': '张三'}
print json.dumps(dict, encoding="UTF-8", ensure_ascii=False)
>>>{'name': '张三'}#打印列表
list = [{'name': '张三'}]
print json.dumps(list, encoding="UTF-8", ensure_ascii=False)
>>>[{'name': '张三'}]

2. Python2.7的UnicodeEncodeError: ‘ascii' codec can't encode异常错误

#重置编码格式
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

乱码一:python不能将汉字的bytes直接输出汉字,需要转换成Unicode,然后用print输出:

str =
b'\xc7\xeb\xca\xb9\xd3\xc3\xca\xda\xc8\xa8\xc2\xeb\xb5\xc7\xc2\xbc\xa1\xa3\xcf\xea\xc7\xe9\xc7\xeb\xbf\xb4'
print(str.decode('gbk'))

输出如下:

请使用授权码登录。详情请看

注意:Python3.X 源码文件默认使用utf-8编码,所以可以正常解析中文,无需指定 UTF-8 编码。

乱码二:

import urllib.parse
c = 'cardId=110110110110&mobile=13123456789&realName=%E6%9D%8E%E9%9B%B7'
res = urllib.parse.unquote(c)
print(res)

输出如下:

cardId=110110110110&mobile=13123456789&realName=李雷

1、demo.py 文件和编码声明都为 GBK

把 demo.py 文件改为 GBK 存储,而且编码声明也是GBK

# encoding:gbk
s = "中文"
print s
print repr(s)1234

2、中文用 unicode 表示

只要在中文前面加上个小u标记,后面的中文就用 unicode 存储了。

# encoding:utf-8
s = u"中文"
print s
print repr(s)1234

cmd 下是可以打印 unicode 字符的,如下。

3、把中文强制转换为GBK或者unicode编码

强制转换为unicode编码,在 Python 中编码是可以互相转换的,比如从utf-8转换为gbk,不同编码之间不能直接转换,需要通过unicode字符集中间过渡下,从上面基础知识可知unicode是一种字符集,不属于编码,而utf-8是具体实现unicode思想的一种编码。utf-8转换为unicode是一种解码过程,通过decode可从utf-8解码成unicode。

# encoding:utf-8
s = "中文"
u = s.decode('utf-8')
print u
print type(u)
print repr(u)123456

强制转换为gbk编码,上一步已经从utf-8转换为unicode了,从unicode是编码的过程,通过encode实现。

# encoding:utf-8
s = "中文"
u = s.decode('utf-8')
g = u.encode('gbk')
print g
print type(g)
print repr(g)1234567

总结 :

windows cmd 窗口下不支持utf-8,想要显示中文必须转换为gbk或者unicode;

而 Python idle 中这三种编码都支持。中文乱码的出现都是由于编码不一致导致的,

存储的是用utf-8,打印的时候用gbk就会乱码了

所以要保证不乱码尽量保持统一,建议全部使用unicode。

decode 解码

从其它编码变成unicode叫解码,解码用的方法是decode;

第一个参数为被解码的字符串原始编码格式,如果写错了也会报错。

比如 s 是utf-8,用gbk去解码就会报错。

# encoding:utf-8
s = "中文"
u = s.decode('gbk')
print u
print repr(u)12345

小提示 :

Python idle 和 cmd 下直接输入 s = "中文"会以 gbk 编码的;

如果在文件中输入 s = "中文"且文件存储格式为utf-8,那么 s 是以utf-8编码存储的。

encode 编码

utf-8转换为gbk,必须经过unicode中间转换,被编码的原始字符串一定要为unicode,否则会报错。

raw_input

raw_input 是获取用户输入值的,获取到的用户输入值和当前运行环境编码有关;

比如 cmd 默认编码是 gbk,那么输入的汉字就是gbk编码,不用demo.py 文件编码格式和编码声明。

# encoding:utf-8
s = raw_input("input something: ")
print s
print type(s)
print repr(s)12345

GBK 编码一个汉字两个字节,UTF-8 一个汉字通常3个字节。

细心的朋友已经注意了,raw_input的提示语我用的是英文,那改成中文看看,果真出现乱码了。

# encoding:utf-8
s = raw_input("请输入中文汉字:")
print s
print type(s)
print repr(s)12345

怎么办呢?把提示字符串强制为gbk编码就好,unicode和utf-8都不可以。

# encoding:utf-8
s = raw_input(u"请输入中文汉字:".encode('gbk'))
print s
print type(s)
print repr(s)12345

相等陷阱

“中文”这两个字符串用不同的编码存储是不一样的,utf-8编码和gbk编码存储的“中文”都不一样。

总结

  1. 文件存储为utf-8格式,编码声明为utf-8,# encoding:utf-8
  2. 出现汉字的地方前面加 u
  3. 不同编码之间不能直接转换,要经过unicode中间跳转
  4. cmd 下不支持utf-8编码
  5. raw_input提示字符串只能为gbk编码

Python进阶干货:[中文编码乱码]:案例及解决方法相关推荐

  1. Python2写csv文件中文乱码问题及解决方法详解

    导读 python2最大的坑在于中文编码问题,遇到中文报错首先加u,再各种encode.decode,这篇文章给大家介绍Python2写csv文件中文乱码问题及解决方法,感兴趣的朋友跟随小编一起看看吧 ...

  2. oracle xe 乱码_关于Linux操作系统下终端乱码的完美解决方法

    初入linux的程序员们,经常会受到乱码的问候.可谓"始乱终弃".因为乱码,并且最终放弃了linux的不在少数.好吧,言归正传,先看看各类乱码是怎么形成的. 中文字符乱码 这种情况 ...

  3. centos php 中文乱码,XShell连接CentOS 7.2显示中文乱码问题的解决方法

    背景 使用U盘往Windows主机.Linux主机传文件还是经常的事,但有时候文件名有中文, 传到Linux机器会有乱码,选择起来也很麻烦,最近刚好遇到,写下解决方法. 环境 Linux [root@ ...

  4. php 写入mysql 乱码,php写入mysql中文乱码的实例解决方法

    php写入mysql中文乱码的实例解决方法 php写入mysql出现中文乱码的解决办法是:在建立数据库连接之后,将该连接的编码方式改为中文. 代码如下: $linkID=@mysql_connect( ...

  5. php pdo 中文乱码,php pdo oracle中文乱码的快速解决方法

    在/etc/profile.d/简历oracle.sh 内容如下在NLS_LANG设置编码ORACLE_HOME=/usr/lib/oracle/12.1/client64 C_INCLUDE_PAT ...

  6. jquery.ajax的url中传递中文乱码问题的解决方法

    jquery.ajax的url中传递中文乱码问题的解决方法 JQuery JQuery默认的contentType:application/x-www-form-urlencoded 这才是JQuer ...

  7. Python错误“ImportError: No module named MySQLdb”解决方法

    Python错误"ImportError: No module named MySQLdb"解决方法 参考文章: (1)Python错误"ImportError: No ...

  8. Anaconda安装Python,提示Python不是内部或外部命令解决方法

    Anaconda安装Python,提示Python不是内部或外部命令解决方法 参考文章: (1)Anaconda安装Python,提示Python不是内部或外部命令解决方法 (2)https://ww ...

  9. php函数substr_replace中文乱码的替代解决方法

    php函数substr_replace中文乱码的替代解决方法 参考文章: (1)php函数substr_replace中文乱码的替代解决方法 (2)https://www.cnblogs.com/ty ...

最新文章

  1. 2018html游戏引擎,跨平台三维游戏引擎Unity Pro 2018.1 Win x64
  2. linux系统运维费用,一般Linux运维学习的费用是多少?Linux学习
  3. 对vuex的一点理解
  4. SpringMVC拦截器之拦截器接口方法演示
  5. CVPR2021-PaperWithCode
  6. nn.Conv2d的解释
  7. 本地仓库的基本操作与概念——Git的学习与使用(三)
  8. 数据治理注意哪些问题
  9. 跟我一起考PMP---项目整合管理
  10. java微信开发页面清除缓存,h5清理微信浏览器网页缓存
  11. 离线数据开发之任务调度系统
  12. 前淘宝工程师:12306几乎是一个奇迹
  13. 2019.10.26日常总结兼一码学成普及模拟4比赛选解
  14. STM32F407单片机读取USR-WIFI232-B2模块的MAC地址
  15. 2011软专高级程序语言T4(二维数组按一维数组访问)
  16. 计算机报名入口官网登录一级,一级计算机考试报名入口诚信互利
  17. 下载工具MLDonkey的优化设置
  18. 浅析如何衡量程序员的生产效率
  19. Python基于OpenCV的智能交通灯系统(南北车流量比例)
  20. 【日常】物联网——嵌入式程序OTA升级功能总结

热门文章

  1. JAVA之Socket编程(技术总结)
  2. TrimLeft TrimRight
  3. 小狐妖京子日式女性3D模型作品欣赏
  4. JAVA计算机毕业设计音乐资源分享网站系统Mybatis+源码+数据库+lw文档+系统+调试部署
  5. zynq操作系统:DDR带宽测试
  6. 南京楼盘坐地起价 增值税成托市疑凶
  7. 3D 组态编辑器,低代码零代码构建数字孪生工厂
  8. 【强化学习实践】 打乒乓球Pong
  9. python xlrd xlwt pandas openxyl导入方法对比 N/A
  10. 从Robocup到RA