Python2 Python3 字符编码总结


本文转至 余子越的博客 ,文章 Python2 Python3 字符编码总结,欢迎访问yuchaoshui.com 了解更多信息!

一、编码与解码

  计算机中存储的信息都是二进制的,编码/解码本质上是一种映射(对应关系),比如字符’a’用ascii编码则是十进制65,计算机中存储的就是二进制00110101,但是显示的时候不能显示00110101,还是要显示’a’,但计算机怎么知道00110101是’a’呢,这就需要解码,当选择用ascii解码时,当计算机读到00110101时就到对应的ascii表里一查发现是’a’,就显示为’a’。

  • 编码:真实字符与二进制串的对应关系,真实字符→二进制串
  • 解码:二进制串与真实字符的对应关系,二进制串→真实字符

二、ascii、gb2312、gbk、unicode、utf-8

1、ascii编码

  ASCII(American Standard Code for Information Interchange,美国信息互换标准代码,ASCⅡ)是一套计算机编码系统。因为计算机只能识别数字,所以有了编码,将字符转换成成对应的数字。共定义了128个字符,对应数字是0-127, 其中33个字符无法显示,在33个字符之外的是95个可显示的字符(包括空格)。

  • 字符0-9 —对应— 十进制 48-57
  • 小写字母a-z —对应— 十进制 97-122
  • 大写字母A-Z —对应— 十进制 65-90

  ascii编码规定,一个英文字符需要一个字节(8bit位)大小,汉字的编码超出了ascii的范围,至少需要两个字节来表示一个中文字符,某些复杂的汉字需要3到6个字节来表示。所以中国制定了GB2312编码,用来把中文编进去。

2、gb2312编码

  gb2312编码是第一个汉字编码国家标准,由中国国家标准总局1980年发布,1981年5月1日开始使用。GB2312编码共收录汉字6763个,其中一级汉字3755个,二级汉字3008个。同时,gb2312编码收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的682个全角字符。

gb2312编码范围:A1A1-FEFE,其中汉字编码范围:B0A1-F7FE。

3、gbk编码

  GBK编码,是对GB2312编码的扩展,因此完全兼容GB2312-80标准。GBK编码依然采用双字节编码方案。共收录汉字和图形符号21886个,其中汉字(包括部首和构件)21003个,图形符号883个。GBK编码方案于1995年12月15日正式发布,这一版的GBK规范为1.0版。

4、unicode编码

  unicode编码是将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,unicode存在的问题就是存储英文时非常浪费存储,大部分是的bit位是空的。

5、utf-8编码

  UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。

三、数据的存在形式

  • 在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。

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

四、Python2 字符编码

  Python2 把字符串分为 unicode、str 两种类型, str 本质上是一种字节码,a="aaa" <type 'str'>, b=u"aaa" <type 'unicode'>

s = "你好yuchaoshui"

  s 变量是个字节码字符串,它本身存储的就是字节码。那么这个字节码是什么格式的?要根据具体的环境来看:

  • 如果这段代码是在解释器上输入的。
    那么这个s的格式就是解释器的编码格式,对于windows的cmd而言,就是gbk,对于Linux来说,就是ascill。当 s 字符串的值不全是英文即包括了汉字时,解释器就会自动地将字符串编码成gbk(windows)、gb2312(windows)、utf-8(linux)的字节流。

  • 如果将代码是保存后才执行的。
    比如存储为utf-8(在文件开头写上 * coding:utf-8 * ),这个utf-8是py文件的编码格式, 在解释器载入这段程序的时候按utf-8解码这个文件。不指定时程序默认按照 ASCII 字符集来解码

  获取解释器的默认编码

import sys
sys.getdefaultencoding()

  设置解释器的默认编码(极力····不推荐)

reload(sys)
sys.setdefaultencoding('utf-8')

  获得系统默认编码格式

import sys
sys.getfilesystemencoding()

  把已经编码的数据解码成unicode(两种方式)。在 Python2中,字符串直接就是字节流的格式数据,所以直接decode成unicode就行。

"你好yuchaoshui".decode("utf-8")    # 使用decode函数
"yuchaoshui".decode("utf-8")        # 使用decode函数
u"你哈"                             # 直接在字符串前面加u 

  把unicode格式数据编码为bytes类型的字节流

u"你好".encode("utf-8")             # 把unicode编码成utf-8
u'\u4f60\u597d'.encode("utf-8")     # 效果同上


五、python3 字符编码

  对于单个字符的编码,Python提供了 ord() 函数获取字符的整数表示,chr() 函数把编码转换为对应的字符

ord('A')结果是65ord('中')结果是20013chr(66)结果是'B'chr(25991)结果是'文'

  在最新的Python 3版本中,字符串是以Unicode编码的。

s = "你好yuchaoshui"

  s 是个unicode格式字符串,它本身存储的就是unicode格式,所以,如果将代码是保存后才执行的,就没必要在文件开头写 * coding:utf-8 * 了。

  • 获取解释器的默认编码
import sys
sys.getdefaultencoding()
  • 设置解释器的默认编码
reload(sys)
sys.setdefaultencoding('utf-8')
  • 把unicode表示的str编码为bytes类型的字节流(两种方式)
name1 = "你好 yuchaoshui"  # name1变量是unicode编码的字符串类型str
name2 = "你好 yuchaoshui".encode("utf-8")   # name2变量是将字符串的值编码成utf-8的字节流了
name3 = "你好 yuchaoshui".encode("gb2312")  # name3变量是将字符串的值编码成gb2312的字节流了
name4 = "hello yuchaoshui".encode("ascii")  # name4变量是将字符串的值编码成ACSII的字节流了
name5 = b"hello yuchaoshui"                 # 字符串被编码成了ASCII表示的字节流
name6 = b"你好 yuchaoshui"                  # 会出错,使用 b"string" 这种方式时,只能用于英文字符,如果有中文则只能用encode函数编码了
  • 把已经编码的数据解码,解码时必须指定正确的解码方式。
b'ABC'.decode('ascii')          # 结果是 'ABC',被解码成unicode
b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')    # 结果是 '中文',被解码成unicode
b'\xe4\xb8\xad\xe6\x96\x877'.decode('utf-8', errors='ignore') # 当解码数据出错时,errors='ignore' 表示忽略出现的错误
  • 判断被编码的数据的编码方式 方法一:
    用尝试法尝试地去解码,解码成功即可得知编码。
coding = ""
for i in ["ascii", "gbk", "gb2312", "utf-8"]:
    try:
        your_string.decode(i)
        coding = i
        break
    except:
        coding = ""

  当try捕捉到异常,也就是不能正常解码时,编码为空,当解码过程顺利时coding被赋值,退出。

  • 判断被编码的数据的编码方式 方法二:
    用模块判断被编码数据的编码方式。
pip3 install chardet

import chardet
chardet.detect(b'abcd')
chardet.detect("你好".encode("utf-8"))
chardet.detect("你好".encode("gb2312"))

  模块判断的方式可能不准确,返回的是一个字典,比如{'encoding': 'utf-8', 'language': '', 'confidence': 0.7525} 有一个字段 confidence 表示准确度。

  • 从文件读取数据、把数据写入文件
f = open("text.txt", "wb")
string1 = "你好 yuchaoshui"
f.write(string1.encode("utf-8"))


f = open("text.txt", "rb")
for line in f:
    print(line.decode("utf-8"))

  当我们用”wb”方式打开文件时,写入的数据也必须是二进制的数据(encode过的)
  当我们用”rb”方式打开文件时,指定的以二进制方式打开,这时就需要自己去解码。

本文转至 余子越的博客 ,文章 Python2 Python3 字符编码总结,欢迎访问yuchaoshui.com 了解更多信息!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值