解决程序中的字符编码问题

今天台风过境,风雨交加,突然就想写一下这个在学习编程初期,非常困扰的问题。
我会尽我所能将这个问题描述清楚,如果有不当之处还请指正!
转载请注明出处即可



字符与字节

字符 就是我们平常看得见的这些,比如 '1','c',"中文", 在程序代码中它们往往表现为一个字符串(其实字符的范围要广得多,还包括不可见的控制字符,后来出现的 emoj 字符等)

但是我们知道其实计算机内部都是只含 01 的二进制序列,于是又引出了两个概念
字节 ,比如 \x31, \xff,它们才是实际在计算机中存储的东西

而从字符到字节的映射,就是 字符编码

ASCII 编码

这是我们经常听到的编码,在 ASCII 编码中,可见字符 '1','2','a','f' 或者 控制字符 '\n','\b' 等都被编码为一个字节

其他编码

其他编码多种多样,比如 GBK,GB2312 等,它们可以表示汉字,将每个汉字编码为多个字节
所以也就出现了所谓 多字节字符 的概念

使用范围最广的应该是 UTF-8 编码,它用 1-6 的字节来编码世界上所有的字符,包括拉丁字符,中文字符,西洋字符,emoj 字符等等,几乎所有

编码报错

了解了这些就能理解为什么 编码出错解码出错 等概念了,乱码 也是一样的道理
哪些地方会出现编码问题呢?我们分几个场景来阐述

  1. 记事本(文本编辑器)

当我们将一堆字符敲完了,保存时文本编辑器一般都会有提示,你想以什么格式保存?

举个栗子会比较直观: 我们敲入了 '中文',保存时选择 UTF-8 编码,那么计算机内部就存储一个 '\xe4\xb8\xad\xe6\x96\x87',如果选择 GBK 编码,那么就存储一个 '\xd6\xd0\xce\xc4',这是编码的过程

相应的我们关闭编辑器后重新打开,可以选择以什么编码格式来打开,这就是解码的过程
所以如果编码方式和解码方式不一致,自然就无法将字节('\xe4\xb8\xad\xe6\x96\x87')转为 我们期望的字符('中文'

了解清楚了么,然后我们开始扩展到更多情景
ps: 不要用记事本写代码,容易编码出错是一方面,主要显得太 low 了

  1. 我们将字符串赋值给一个变量,然后输出到屏幕

这里除了要保证源代码文件保存时的编码和重新打开时的编码一致之外,多了一点需要注意

当程序运行起来的时候,程序内部也有自己的编码方式(wtf?),这里以 python2 为例

python2 内部默认格式是 unicode ,然而它也允许另外一种格式 str,em...

>>> s = '中文'
>>> s
'\xe4\xb8\xad\xe6\x96\x87'
>>> type(s)
<type 'str'>

可以看到这就是我们的字符串它的类型是 str,编码方式是 UTF-8
所以我们用 UTF-8 来解码一下,嗯,得到了一个 unicode 类型,真不错

>>> s.decode('utf-8')
u'\u4e2d\u6587'
>>> type(s.decode('utf-8'))
<type 'unicode'>

python 一定也是这么做的吧
no... 在 python2 中,默认使用 ascii 格式来处理的
也就是说,当 python2 检测到该字符串不是 unicode 类型,就尝试用 ascii 去解码,即 s.decode('ascii')
相应的,在输出的时候,检测到该字符串不是 str 类型,就尝试用 ascii 去编码

所以你就遇到了这样两个错误
UnicodeEncodeError: 'ascii' codec can't encode characters
UnicodeDecodeError: 'ascii' codec can't decode characters

对于这个编码转换发生在什么时候我不太清楚,知道的请告诉我!
不过这样下去总不是个事儿
最好的解决方法就是迁移到 python3 吧(强烈推荐)

python3 统一了字符串表示用 str,内部存储用的是 bytes,默认编码格式是 UTF-8!
更多信息自己去查询,这里有点跑偏了

  1. 我们浏览网页的时候

与上述情况类似,数据在网络上传播的形式是 比特流/字节流,这就意味着还是要编码

存储在服务器的网页信息(字符),在服务端编码变成比特流/字节流,然后我们的浏览器拿到这些比特流/字节流,解码成(我们实际看到的)网页(字符)

编码解码不一致就又会乱码啦!
不过一般网页都会指定编码方式 <meta charset="utf-8"/>
浏览器也会按指定格式解码,一般没事
出错了调整下浏览器编码方式试试

结语

差不多就这么多了,点个关注嘛..

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343