知行编程网知行编程网  2022-10-31 04:30 知行编程网 隐藏边栏  0 
文章评分 0 次,平均分 0.0
导语: 本文主要介绍了关于Python之字符编码汇总的相关知识,包括汉字字符编码,以及python 字符编码这些编程知识,希望对大家有参考作用。


Python字符编码总结


一、常见编码

ASCII:ASCII 是美国信息交换标准代码。由于计算机内部的所有信息最终都是一个二进制值,而每个二进制位(bit)有两种状态,0和1,所以8个二进制位可以组合成256个状态,称为一个字节(byte)。 )。标准的 ASCII 码一共规定了 128 个字符的编码,因为只使用了最后 7 位,而且第一个统一指定为 0。之后 IBM 开发了 128 个扩展字符,不是标准的 ASCII 码,而是用于表示框架线、音标和其他欧洲非英文字母。

用128个符号来编码英文就够了,但要表示其他语言,128个符号是不够的,而且不同国家使用的字母也不同,有些国家使用的字符远不止256个。显然,ASCII 已经不够用了。问题解决了。那么有没有统一唯一的编码方式呢?答案是 Unicode。

Unicode:Unicode 是计算机科学领域的行业标准。创建 Unicode 是为了解决传统字符编码方案的局限性。它为每种语言中的每个字符设置了统一且唯一的二进制编码,以满足跨语言、跨平台的文本转换和处理的要求。

但是Unicode也有问题。比如“中”这个词的Unicode编码是16进制的4E2D,也就是二进制的100111000101101占用15位,也就是说这个符号至少需要两个字节,那么怎么知道这两个字节代表一个字符而不是两个字符分开?也就是如何区分Unicode和ASCII?

UTF-8:UTF是“Unicode Transformation Format”的缩写,可以翻译成Unicode字符集转换格式。 UTF-8 是 Internet 上使用最广泛的 Unicode 实现。其他实现包括 UTF-16(字符由两个字节或四个字节表示)和 UTF-32(字符由四个字符表示)部分表示。 UTF-8 的一个特点是它是一种可变长度编码方法。它可以用1到6个字节来表示一个符号,字节长度根据不同的符号而变化。对于一个字符的UTF-8编码,如果只有一个字节,二进制最高位为0;如果是多字节,则第一个字节从最高位开始,连续二进制位数为 1 确定编码的位数,其余字节从 10 开始。

字节数 | UTF-8编码(二进制)

1 | 0xxxxxxx

2 | 110xxxxx 10xxxxxx

3 | 1110xxxx 10xxxxxx 10xxxxxx

4 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

5 | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

6 | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

很明显“中”字使用UTF-8编码需要三个字节,所以从“中”字的最后一个二进制位开始,按格式从后往前填写x,将 0 添加到额外的位。 .这样就得到了“中”字的UTF-8编码,结果为:11100100 10111000 10101101,即十六进制的E4B8AD。


二、Python3编码

Python中的编码问题困扰了我很久,尤其是Python2和Python3的区别,这里只讨论Python3中的编码问题。

Python 3 最重要的新特性可能是文本和二进制数据之间更清晰的区别。文本总是Unicode,用str类型表示,二进制数据用bytes类型表示,两者之间的转换用编码(encode)和解码(decode)实现来表示。这里可以看一下Python的官方文档:

str.encode(encoding="utf-8", errors="strict")
  Return an encoded version of the string as a bytes object. Default encoding is 'utf-8'. errors may be given to 
  set a different error handling scheme. The default for errors is 'strict', meaning that encoding errors raise 
  a UnicodeError. Other possible values are 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' and any 
  other name registered via  codecs.register_error(), see section Error Handlers. For a list of possible encodings, 
  see section Stardard Encodings.
 
bytes.decode(encoding="utf-8", errors="strict")
  Return a string decoded from the given bytes. Default encoding is 'utf-8'. errors may be given to set a different 
  error handling scheme. The default for errors is 'strict', meaning that encoding errors raise a UnicodeError. 
  Other possible values are 'ignore', 'replace' and any other name registered via codecs.register_error(), see 
  section Error Handlers. For a list of possible encodings, see section Stardard Encodings.

可以看出str没有decode方法,因为是Unicode编码的,而bytes没有encode方法,而且encode和decode都是默认UTF-8编码的。当然,我们也可以使用其他方法进行编码。和解码,如:

s = "博客园"
print(s.encode())
print(s.encode("utf-16"))
print(s.encode("gbk"))
# b'\xe5\x8d\x9a\xe5\xae\xa2\xe5\x9b\xad'
# b'\xff\xfeZS\xa2[\xedV'
# b'\xb2\xa9\xbf\xcd\xd4\xb0'

那么对于一些数据,如果我们不知道它的编码格式怎么办?在Python3中,可以使用chardet模块中的detect方法查看:

import chardet
print(chardet.detect(b'\xe5\x8d\x9a\xe5\xae\xa2\xe5\x9b\xad'))
print(chardet.detect(b'\xff\xfeZS\xa2[\xedV'))
{'encoding': 'utf-8', 'confidence': 0.87625, 'language': ''}
{'encoding': 'UTF-16', 'confidence': 1.0, 'language': ''}

检测方法返回一个包含编码方法、检测到的概率和语言信息的字典。可以看出,使用chardet检测编码使用起来很简单。得到编码后,可以转换成str,方便后续处理。


三、文本编码

首先新建一个文本文档“test.txt”,内容为:“博客园博客”,然后选择“另存为”,可以看到使用的是默认的ANSI编码:

Python字符编码总结

那么这个 ANSI 编码是什么?不同的国家和地区制定了不同的标准,产生了自己的编码标准如GB2312、GBK、Big5、Shift_JIS。这些使用1到4个字节来表示一个字符的各种中文扩展编码,称为ANSI编码。在简体中文Windows操作系统中,ANSI编码代表GBK编码。那么如果我们使用默认的ANSI编码,也就是GBK编码,那么在读取文本的时候会发生什么呢?

with open("test.txt", 'r') as f:
    print(f.read())
# 博客园Blogs
with open("test.txt", 'r', encoding="gbk") as f:
    print(f.read())
# 博客园Blogs
with open("test.txt", 'r', encoding="utf-8") as f:
    print(f.read())
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb2 in position 0: invalid start byte

可以看到使用UTF-8编码时会报错,因为有无法解码的字符。那么如果我们在保存的时候使用UTF-8编码呢?

with open("test.txt", 'r') as f:
    print(f.read())
# 锘垮崥瀹㈠洯Blogs
with open("test.txt", 'r', encoding="gbk") as f:
    print(f.read())
# 锘垮崥瀹㈠洯Blogs
with open("test.txt", 'r', encoding="utf-8") as f:
    print(f.read())
# 博客园Blogs

很明显,使用GBK编码时出现乱码。原因是编码和解码方式不一致,导致最后出现乱码。


四、URL编码

URL 是统一资源定位器(Uniform Resource Locator)。一般来说,URL只能使用英文字母、阿拉伯数字和一些标点符号,而不能使用其他文字和符号,因为网络标准RFC1738已经做出了规定。这意味着如果 URL 中有汉字,则必须对其进行编码和使用。但麻烦的是RFC1738并没有指定具体的编码方式,而是让应用程序(浏览器)来决定。

这里我们可以任意打开一个网页,比如百度百科关于编码,可以看到浏览器显示的链接没有问题:

Python字符编码总结

复制一下,然后粘贴过来看看:https://baike.baidu.com/item/%E7%BC%96%E7%A0%81/80092,可以看到“encoding”这个词是自动编码的被浏览器变成“%E7%BC%96%E7%A0%81”。这里我们需要知道的是,“code”的UTF-8编码为:E7BC96,而“code”的UTF-8编码为:E7A081,所以“%E7%BC%96%E7%A0%81”是在每个单词前面加上一个“%”得到的,表示URL路径是用UTF-8编码的。

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享