首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Unicode和UTF-8

(Photo byMarkus SpiskeonUnsplash)

今天看到这篇讲解Python字符编码的文章时,我觉得需要巩固一下对字符编码这块内容的理解,深入看下去之后,挖掘出来很多新的内容。

我们都知道Python2默认使用ASCII字符编码(Python3默认使用UTF-8字符编码),因为Python2这门语言发布的时候,Unicode编码还没有诞生,见这篇文章Python编码为什么那么蛋疼?。在写程序过程中经常会遇到UnicodeEncodeError和UnicodeDecodeError,如果没有彻底搞懂,会让人很崩溃,每次都得额外花费时间去搜索解决办法,为什么不一次性弄懂把它刻在脑子里呢?

这篇总结,就给你提供一个一次性弄懂的机会。

Python 2.7.12 Anaconda 2.3.0 (x86_64) (default, Jul 2 2016, 17:43:17)

[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)] on darwin

Type "help", "copyright", "credits" or "license" for more information.Anaconda is brought to you by Continuum Analytics.Please check out:http://continuum.io/thanksandhttps://anaconda.org>>> import sys>>> sys.getdefaultencoding()'ascii'(在终端使用命令查看Python2.7默认的编码方式)

Unicode和UTF-8转换规则

当我看完讲解Python字符编码这篇文章后,我才知道UTF(Unicode Transfer Format,通用传输格式)的作用是定义Unicode字符存储和传输的格式。

通过这篇文章里给出的链接,我读到了阮一峰老师2007年写的字符编码笔记:ASCII,Unicode 和 UTF-8,写得非常好,UTF-8编码只是Unicode字符集的一种实现方式,Unicode还有UTF-16、UTF-32(基本废弃不使用)等实现形式,文中还给出了Unicode和UTF-8编码方式的转换关系,如下。

Unicode符号范围 UTF-8编码方式

(十六进制) (二进制)

--------------------+------------------------------------

0000 0000-0000 007F 0xxxxxxx

0000 0080-0000 07FF 110xxxxx 10xxxxxx

0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx

0001 0000-0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx(Unicode和UTF-8编码方式的转换关系)

当我们存储或传输字符时,存储和传输的是字符的比特流信息,不是字符本身。计算机世界最开始只用ASCII字符编码,发现ASCII不够用之后进化为UTF-16字符编码,后来UTF-16还是不够用,就进化为UTF-8字符编码。其间,各个国家都各自搞一套字符集,最终被标准化组织统一形成了Unicode字符集。尽管操作系统各不相同,但在计算机内存中统一使用Unicode字符集,当需要将内存中的数据向硬盘中存储或向网络传输时,就转换为你指定的编码方式,比如UTF-8。

计算机内存中统一使用Unicode字符集?

我认同这个观点。我这样理解它,比如Java语言某些数据类型使用UTF-16编码,Python2默认使用ASCII编码(当然你可以在程序开头写"# -*- coding: utf-8 —"表明用UTF-8编码),Python3默认使用UTF-8编码,Ubuntu默认使用UTF-8编码,Win7中文版默认使用GBK编码(在GB2312上面的拓展版本),在这些系统或应用中定义同一个字符,尽管长度不一,但字符的Unicode字符是相同的,字符在内存中以Unicode字符定义的二进制式形式存在,虽然多字节字符在内存中有大端小端问题需要考虑(单字节字符没有大端小端问题),但它们可以被正确转换、识别。

记事本使用UTF-16编码的例子

请注意看阮一峰老师文章中举的例子,不然不太好理解Unicode和UTF-8的转换规则。在看到Python之禅指出阮一峰文章中的常识性错误一文之后,我才知道Windows记事本另存为时,编码方式中的Unicode和Unicode big endian其实就是UTF-16编码方式,前者是小端存储,后者是大端存储。

内容有点多,如果没有基础,可能不大容易消化得过来,建议多看几遍,加强理解。

汉字的UTF-8和Unicode展现形式

我们先看一下下面这个例子。

Python2.7环境,我们Print变量a和直接显示变量a,它在终端里显示出来的内容是不一样的。直接显示变量a,打出来的是'汉'这个字的UTF-8编码格式-'\xe6\xb1\x89','汉'这个字的Unicode编码是u'\u6c49'。Unicode编码是汉字在内存中的真实存在形式,而UTF-8编码是汉字的一种显示、存储或传输形式,那怎么样由Unicode编码转换为UTF-8编码,或者怎么由UTF-8编码转换为Unicode编码呢,答案是按照上图的转换规则转变而来。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180209G00ZUX00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券