python3编码&解码

一、字符编码中ASCII、Unicode和UTF-8的区别

以下内容来源于博客:https://www.cnblogs.com/moumoon/p/10988234.html

1. 编码介绍

     最早只有127个字母被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。
     但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。
     你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。
     因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。
     新的问题又出现了:如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。
     所以,本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间。UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。

  1. ASCII

ASCII 只有127个字符,表示英文字母的大小写、数字和一些符号,但由于其他语言用ASCII 编码表示字节不够,例如:常用中文需要两个字节,且不能和ASCII冲突,中国定制了GB2312编码格式,相同的,其他国家的语言也有属于自己的编码格式。

  1. Unicode

由于每个国家的语言都有属于自己的编码格式,在多语言编辑文本中会出现乱码,这样Unicode应运而生,Unicode就是将这些语言统一到一套编码格式中,通常两个字节表示一个字符,而ASCII是一个字节表示一个字符,这样如果你编译的文本是全英文的,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。

  1. UTF-8

为了解决上述问题,又出现了把Unicode编码转化为“可变长编码”UTF-8编码,UTF-8编码将Unicode字符按数字大小编码为1-6个字节,英文字母被编码成一个字节,常用汉字被编码成三个字节,如果你编译的文本是纯英文的,那么用UTF-8就会非常节省空间,并且ASCII码也是UTF-8的一部分。

2.三者之间的联系

搞清楚了ASCII、Unicode和UTF-8的关系,我们就可以总结一下现在计算机系统通用的字符编码工作方式:
(1) 在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
(2)用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。如下图:
在这里插入图片描述
浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器:
在这里插入图片描述

二、使用

1. 通用知识点

  • 在python中,字符串是以Unicode编码的。最新的Python 3版本中,字符串是以Unicode编码的,也就是说,Python的字符串支持多语言
  • 在网络上传输,或者保存到磁盘上,就需要把Unicode编码的str变为以字节为单位的bytes
  • python中编码转换方法:编码decode() & 解码encode(),编码与解码过程:
     字符|—–编码encode —-> |byte字节流| ———-解码decode——–>|字符
  • UTF-8、GBK(GB2312)…
# -*- coding:utf-8 -*-

a = '\u563f\uff0c\u5582'
print(a)

ver  = "男儿何不带吴钩,收取关山五十州。请君暂上凌烟阁,若个书生万户侯?"
print(ver) # <class 'str'>


########## encode() ------》编码
ver_bytes = ver.encode() #return <class 'bytes'> 
print(ver_bytes)
''' return
b'\xe5\xbe\x97\xe6\x97\xb6\xe6\x97\xa0\xe6\x80\xa0\xef\xbc\x8c
\xe6\x97\xb6\xe4\xb8\x8d\xe5\x86\x8d\xe6\x9d\xa5\xef\xbc\x8c\xe5
\xa4\xa9\xe4\xba\x88\xe4\xb8\x8d\xe5\x8f\x96\xef\xbc\x8c\xe5\x8f
\x8d\xe4\xb8\xba\xe4\xb9\x8b\xe7\x81\xbe\xe3\x80\x82'
'''
ver_bytes_utf8 = ver.encode('utf-8') #return <class 'bytes'> by utf-8
print(ver_bytes_utf8)
#另一种写法:
ver_bytes_utf8 = ver.encode(encoding='utf-8', errors='strict') #return <class 'bytes'> by utf-8
print(ver_bytes_utf8)

ver_bytes_gbk = ver.encode('gbk') #return <class 'bytes'> by gbk
print(ver_bytes_gbk)

ver_bytes_unicode_escape = ver.encode('unicode_escape') #return <class 'bytes'> by unicode
print(ver_bytes_unicode_escape)


########## decode() ------》编码
ver_str_unicode = ver.encode('unicode_escape').decode() #return <class 'str'>, 当前str以unicode编码展现
print(ver_str_unicode)
''' return
\u5f97\u65f6\u65e0\u6020\uff0c\u65f6\u4e0d\u518d\u6765
\uff0c\u5929\u4e88\u4e0d\u53d6\uff0c\u53cd\u4e3a\u4e4b\u707e\u3002
'''
str_unicode = '\u7537\u513f\u4f55\u4e0d\u5e26\u5434\u94a9\uff0c\u6536\u53d6\u5173\u5c71\u4e94\u5341\u5dde\u3002\u8bf7\u541b\u6682\u4e0a\u51cc\u70df\u9601\uff0c\u82e5\u4e2a\u4e66\u751f\u4e07\u6237\u4faf\uff1f'
print(str_unicode)

print(ver_bytes_utf8.decode('utf-8'))

print(ver_bytes_gbk.decode('gbk'))


2. 编码常见报错

针对报错:#UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x80 in position 15: illegal multibyte sequence,两种解决方案:
参见:https://blog.youkuaiyun.com/qq_40494873/article/details/120474070

# -*- coding:utf-8 -*-
import os, locale
from ProcessorFile import config
normal_file = os.path.join(config.input_path, 'read_test.txt')

#针对编码问题报错:#UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 15: illegal multibyte sequence
#两种解决方案

#添加参数, encoding,指定读取编码
with open(normal_file, 'r', encoding='utf-8') as f:
    line = f.readline()
    while line:
        print(line) #include \n
        print(type(line))
        line = f.readline()

#改变读取模式,以二进制形式读取,然后输出的时候使用decode解码
with open(normal_file, 'rb') as f:
    line = f.readline()
    while line:
        print(line.decode())
        line = f.readline()

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值