PYTHON 之 蛋疼的编码

本文深入探讨了字符编码的发展历程,从ASCII、GB2312、GBK到Unicode和UTF系列,详细解析了每种编码的特点与局限性。尤其强调了Unicode作为全球通用编码的重要性和Python在处理字符编码上的演变。

作者:知乎用户
链接:https://www.zhihu.com/question/31833164/answer/381137073
在这里插入图片描述

各类编码

看这篇文章前,你应该已经知道了为什么有编码,以及编码的种类情况

  • ASCII 占1个字节,只支持英文
  • GB2312 占2个字节,支持6700+汉字
  • GBK GB2312的升级版,支持21000+汉字
  • Shift-JIS 日本字符
  • ks_c_5601-1987 韩国编码
  • TIS-620 泰国编码

由于每个国家都有自己的字符,所以其对应关系也涵盖了自己国家的字符,但是以上编码都存在局限性,即:仅涵盖本国字符,无其他国家字符的对应关系。

应运而生出现了万国码,他涵盖了全球所有的文字和二进制的对应关系:

  • Unicode 2-4字节 已经收录136690个字符,并还在一直不断扩张中…

Unicode 起到了2个作用:

  • 直接支持全球所有语言,每个国家都可以不用再使用自己之前的旧编码了,用unicode就可以了。(就跟英语是全球统一语言一样)
  • unicode包含了跟全球所有国家编码的映射关系,

Unicode解决了字符和二进制的对应关系,但是使用unicode表示一个字符,太浪费空间。例如:利用unicode表示“Python”需要12个字节才能表示,比原来ASCII表示增加了1倍。

由于计算机的内存比较大,并且字符串在内容中表示时也不会特别大,所以内容可以使用unicode来处理,但是存储和网络传输时一般数据都会非常多,那么增加1倍将是无法容忍的!!!

为了解决存储和网络传输的问题,出现了Unicode Transformation Format,学术名UTF,即:对unicode中的进行转换,以便于在存储和网络传输时可以节省空间!

  • UTF-8: 使用1、2、3、4个字节表示所有字符;优先使用1个字符、无法满足则使增加一个字节,最多4个字节。英文占1个字节、欧洲语系占2个、东亚占3个,其它及特殊字符占4个
  • UTF-16: 使用2、4个字节表示所有字符;优先使用2个字节,否则使用4个字节表示。
  • UTF-32: 使用4个字节表示所有字符;总结:UTF 是为unicode编码 设计 的一种 在存储 和传输时节省空间的编码方案。

编码的转换

虽然国际语言是英语 ,但大家在自己的国家依然说自已的语言,不过出了国, 你就得会英语编码也一样,虽然有了unicode and utf-8 , 但是由于历史问题,各个国家依然在大量使用自己的编码,比如中国的windows,默认编码依然是gbk,而不是utf-8

基于此,如果中国的软件出口到美国,在美国人的电脑上就会显示乱码,因为他们没有gbk编码。若想让中国的软件可以正常的在 美国人的电脑上显示,只有以下2条路可走:

  • 让美国人的电脑上都装上gbk编码
  • 把你的软件编码以utf-8编码

PYTHON 字符编码

https://www.zhihu.com/question/31833164/answer/381137073
为了在源码中支持非ASCII字符,必须在源文件的第一行或者第二行显示的指定编码格式

#!/usr/bin/env python
# -*- coding: utf8 -*-

或者

# coding = utf-8

PYTHON编码历史

由于Python创始人在开发初期认知的局限性,其并未预料到python能发展成一个全球流行的语言,导致其开发初期并没有把支持全球各国语言当做重要的事情来做,所以就轻佻的把ASCII当做了默认编码。

当后来大家对支持汉字、日文、法语等语言的呼声越来越高时,Python于是准备引入unicode,但若直接把默认编码改成unicode的话是不现实的, 因为很多软件就是基于之前的默认编码ASCII开发的,编码一换,那些软件的编码就都乱了。

PYTHON 2 编码

所以Python 2 就直接搞了一个新的字符类型,就叫unicode类型,比如你想让你的中文在全球所有电脑上正常显示,在内存里就得把字符串存成unicode类型

>>> s = "路飞"
>>> s
'\xe8\xb7\xaf\xe9\xa3\x9e'
>>> s2 = s.decode("utf-8")
>>> s2
u'\u8def\u98de'
>>> type(s2)
<type 'unicode'>

时间来到2008年,python发展已近20年,创始人龟叔越来越觉得python里的好多东西已发展的不像他的初衷那样,开始变得臃肿、不简洁、且有些设计让人摸不到头脑,比如unicode 与str类型,str 与bytes类型的关系,这给很多python程序员造成了困扰。龟叔再也忍不了,像之前一样的修修补补已不能让Python变的更好,

PYTHON 3 编码

于是来了个大变革,Python3横空出世,不兼容python2,python3比python2做了非常多的改进,其中一个就是终于把字符串变成了unicode,文件默认编码变成了utf-8,这意味着,只要用python3,无论你的程序是以哪种编码开发的,都可以在全球各国电脑上正常显示,真是太棒啦!

PY3 除了把字符串的编码改成了unicode, 还把str 和bytes 做了明确区分, str 就是unicode格式的字符, bytes就是单纯二进制啦。
在这里插入图片描述

最后一个问题,为什么在py3里,把unicode编码后,字符串就变成了bytes格式? 你直接给我直接打印成gbk的字符展示不好么?我想其实py3的设计真是煞费苦心,就是想通过这样的方式明确的告诉你,

想在py3里看字符,必须得是unicode编码,其它编码一律按bytes格式展示

好吧,就说这么多吧。 最后再提示一下,Python只要出现各种编码问题,无非是哪里的编码设置出错了常见编码错误的原因有:

  • Python解释器的默认编码
  • Python源文件文件编码
  • Terminal使用的编码
  • 操作系统的语言设置

掌握了编码之前的关系后,挨个排错就好啦

python之bytes和string

在这里插入图片描述
转自:https://www.cnblogs.com/skiler/p/6687337.html

  • 1、bytes主要是给在计算机看的,string主要是给人看的

  • 2、中间有个桥梁就是编码规则,现在大趋势是utf8

  • 3、bytes对象是二进制,很容易转换成16进制,例如\x64

  • 4、string就是我们看到的内容,例如’abc’

  • 5、string经过编码encode,转化成二进制对象bytes,给计算机识别

  • 6、bytes经过反编码decode,转化成string,让我们看,但是注意反编码的编码规则是有范围,\xc8就不是utf8识别的范围

实例:
#!/usr/bin/env python
# -*- coding: utf8 -*-
# __Author: "Skiler Hao"
# date: 2017/4/9 15:26
import hashlib
#字节对象b
b = b"example"
#字符串对象s
s = "example"
print(b)
print("example")
将字符串转换为字节对象
#将字符串转换为字节对象
b2 = bytes(s,encoding='utf8')  #必须制定编码格式
# print(b2)
#字符串encode将获得一个bytes对象
b3 = str.encode(s)
b4 = s.encode()
print(b3)
print(type(b3))
print(b4)

将字节对象decode将获得一个str对象
#将字节对象decode将获得一个str对象
s2 = bytes.decode(b)
s3 = b.decode()
print(s2)
print(s3)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值