Python Unicode和string那些事

本文转载自https://www.jianshu.com/p/4ced2bbc9334

开发过程中总是会碰到string,Unicode,ASCII,中文字符等编码的问题,本文力求搞清楚Python的string和Unicode到底是怎么回事!

基础知识

我们都知道计算机只认0和1,要想在计算机显示26个字母,就要给他们一套映射规则:计算机能认得的符号——>人类可读的符号,这转换的过程就是一套编码规则。

  • 字符集:就是一套字符的集合(比如中文4000个汉字集合)
  • 字符编码:一套法则,能够将0/1和人类的语言之间进行转换的法则

最初字符集比较少,ASCII码就够用了(一些控制符和26个字母),随着计算机的发展,各国语言都有自己独特的编码,汉字的编码也不断地扩展,从GBK到GB18030/DBCS,这个时候Unicode应运而生。

Unicode就是为了统一各国各地区的编码规则,重新搞了一套包罗地球上所有文化,符号的字符集!Unicode没有编码规则,只是一套包含全世界符号的字符集;Unicode也不完美,于是后续有了众多UTF编码(UTF-8,UTF-16)。

  • 总之搞清楚一件事情,一个字符用了UTF-8编码的,就要用UTF-8去解码,不然就会出现乱码。

文本处理

在Python-2.x,处理文本时,有string和Unicode两种类型

  • str类型就是一串bytes,这种类型跟C语言中处理string是非常相似的
  • Unicode是一串Unicode的数字映射(code point),用于映射某个字符与一个unicode的对应关系

看看代码出来是如何的:

>>> a = "简书"
>>> type(a)
<type 'str'>
>>> a
'\xe7\xae\x80\xe4\xb9\xa6'
>>> print a
简书
>>>
>>>
>>> u = u"简书"
>>> type(u)
<type 'unicode'>
>>> u
u'\u7b80\u4e66'
>>> print u
简书

从上面的代码可以看到,a = "简书"是string类型,可以看到a是一串'\xe7\xae\x80\xe4\xb9\xa6' byte字符,而u = u"简书" 是一串u'\u7b80\u4e66'的Unicode数字,通过print aprint u可以显示出中文字符。

常见问题#1

大家经常犯的一个错误就是混淆了Unicode以及通过Unicode编码存储在string里面的类型。比如上面的例子中u'\u7b80\u4e66'是Unicode,u'\u7b80\u4e66'是byte string,byte和Unicode之间一一对应,可以相互转换,转换规则如下:

>>> '\xe7\xae\x80'.decode('utf-8')
u'\u7b80'
>>> print '\xe7\xae\x80'.decode('utf-8')
简
>>>
>>> u'\u7b80'.encode('utf-8')
'\xe7\xae\x80'
>>> print u'\u7b80'.encode('utf-8')
简

总结一下,上面例子中:

  • Unicode和byte都指
  • byte string 里面存储的是Unicode通过utf-8编码后得到的bytes
  • 所以byte string解码(decode)后即可得到Unicode
  • Unicode是byte string通过utf-8解码后得到的
  • Unicode用utf-8编码(encode)可以得到对应的bytes

Note:

​ 总而言之 Unicode ———编码———>byte string

​ Unicode<———解码———byte string

Unicode就像是加密传输中的明文,可以用utf-8,utf-16,utf-7,utf-32等对Unicode进行加密,最后解密还是要用回原本的加密方式来解密,不然就解出乱码啦。

常见问题#2

对Unicode或者byte string编码解码方向搞错

>>> u'\u7b80'.decode('utf-8')
Traceback (most recent call last):File "<stdin>", line 1, in <module>File "D:\appinstallation\AnacondaInstallation\envs\pyth
on2\lib\encodings\utf_8.py", line 16, in decodereturn codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode character
u'\u7b80' in position 0: ordinal not in range(128)
>>>
>>>
>>> '\xe7\xae\x80'.encode('utf-8')
Traceback (most recent call last):File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7
in position 0: ordinal not in range(128)

Unicode应该是进行编码的,如果进行decode,是会出现UnicodeEncodeError异常的,bytes string同理,应该进行解码,如果硬要进行编码的话,则抛出UnicodeDecodeError

常见问题#3

API调用不一致的问题,在调用别人的API的时候,需要看清楚是传Unicode还是byte string作为参数,因为第三方的API有的是支持Unicode,有的是byte string,甚至有的两种类型都支持,这个时候要清除自己传进去的参数是什么,比如一些变量值是从htpp requests里面拉过来的,这个时候你获得的变量值很有可能是Unicode类型(python requests get/post把返回值都转成了Unicode),而如果第三方的API需要byte string,那么就需要自己判断一下并进行转换,否则就会出现各种奇怪的UnicodeError

  • 虽然python社区规定了在所有的API中使用Unicode,但是少数一部分的API处于安全考虑还是要求使用byte string,需要注意一下。

常见问题#4

输出的类型不一致。
既然python社区推动到处使用Unicode,那么我们只要在开发过程中全部都转成Unicode是不是就万事大吉了?并不是,当你要输出文本到terminal或者到文件,这个文本必须是byte string类型的。
如果不是的话,python会隐式地帮你将Unicode转成string,python默认采用ASCII编码,而中文编码不在ASCII编码能够表示的范围之内,所以string无法将“你好”作为ASCII编码保存为str类型。
所以当你需要输出的时候,需要将你的Unicode转换成byte string再写文件,如果有中文的话,要用’utf-8’或’GBK’等支持中文的编码。

本文转载自https://www.jianshu.com/p/4ced2bbc9334

Python Unicode和string相关推荐

  1. python unicode编码转换中文_python unicode转中文及转换默认编码

    一. 在爬虫抓取网页信息时常需要将类似"\u4eba\u751f\u82e6\u77ed\uff0cpy\u662f\u5cb8"转换为中文,实际上这是unicode的中文编码.可 ...

  2. django BUG!!! === Django model coercing to Unicode: need string or buffer, XXX found

    coercing to Unicode: need string or buffer, datetime.datetime found coercing to Unicode: need string ...

  3. Python bytearray/bytes/string区别 - Python零基础入门教程

    目录 一.字节与字符的区别 1.字节概念 2.字符概念 3.字符串概念 4.字节串概念 二.str / bytes / bytearray 区别 三.string 与 bytes / bytearra ...

  4. Python bytearray/bytes/string区别

    目录 一.字节与字符的区别 1.字节概念 2.字符概念 3.字符串概念 4.字节串概念 二.str / bytes / bytearray 区别 三.string 与 bytes / bytearra ...

  5. python unicode码转换_python实现unicode转中文及转换默认编码的方法

    本文实例讲述了python实现unicode转中文及转换默认编码的方法.分享给大家供大家参考,具体如下: 一.在爬虫抓取网页信息时常需要将类似"\u4eba\u751f\u82e6\u77e ...

  6. python unicode转字符串_Python: 在Unicode和普通字符串之间转换

    Unicode字符串可以用多种方式编码为普通字符串, 依照你所选择的编码(encoding):Toggle line numbers1 #将Unicode转换成普通的Python字符串:"编 ...

  7. Python Unicode 基本知识

    Python Unicode 基本知识 本文讨论了 Python 2.x 对 Unicode 的支持,并对人们在使用 Unicode 时常遇到的问题进行了解释. Unicode 简介 1. 字符编码历 ...

  8. python null byte_如何以“正确”的方式处理带有nullbytes的Python unicode字符串?

    问题 PyWin32似乎很乐意将以null结尾的unicode字符串作为返回值.我想用"正确"的方式处理这些字符串.在 假设我得到一个字符串:u'C:\\Users\\Guest\ ...

  9. Python bytes 和 string 相互转换 - Python零基础入门教程

    目录 一.Python bytes 和 string 区别 二.Python string 转 bytes 三. Python bytes 转 string 四.猜你喜欢 基础 Python 学习路线 ...

最新文章

  1. 芒果TV 2021 互联网人才招聘
  2. js 实现2的n次方计算函数_密码杂凑函数的基本性质探讨
  3. 【1】Docker概述
  4. (23)Verilog HDL条件语句:if-else语句
  5. 蓝桥杯 BEGIN-3 入门训练 圆的面积
  6. android学习日记20--连接组件之Intent和IntentFilter
  7. c++ STL之queue
  8. 如何破解“仅三天可见”的朋友圈?
  9. 档案管理学川大972 | 档案信息资源开发与利用
  10. luogu P5560 [Celeste-B]Golden Feather
  11. 深入了解C/C++开发就业前景如何?
  12. python 异步io 写excel_python异步IO编程(二)
  13. Error: spawn node.cmd ENOENT node自启动工具supervisor cmd运行报错解决方法
  14. kubeadm部署kubernetes集群
  15. 虚拟地址转换成物理地址
  16. word课程表设置符号与编号_Word2003文档怎么添加编号
  17. Freebase再研究
  18. SC662K 输入6V 输出3.3V 250mA 线性LDO
  19. 2.2案例:鸢尾花分类——逻辑回归
  20. 电脑上使用计算机命令行,我的电脑运行命令_我的电脑什么运行命令

热门文章

  1. 关闭谷歌浏览器开发者工具中的 chrome-extension 网络请求
  2. Form 表单提交的几种方式
  3. VC6 下 libpng 库的编译与初步使用以及压缩与解压缩
  4. Vue数据绑定(单向绑定,双向绑定)
  5. 英语口语练习系列-C25-冒险-课堂用语-葬我
  6. 创领3G 多普达首款TD手机S700将上市
  7. mysql数据库学生表结构_Mysql表结构
  8. Linux 挂载磁盘和扩展现有分区大小(无需格式化、无需关机)
  9. Word、Excel中输入当前日期及时间的快捷键
  10. 如何远程连接MySQL数据库