浅析Python 3 字符串中的 STR 和 Bytes 有什么区别


Posted in Python onOctober 14, 2018

Python2的字符串有两种:str和Unicode,Python3的字符串也有两种:str和Bytes。Python2的str相当于Python3的Bytes,而Unicode相当于Python3的Bytes。

Python2里面的str和Unicode是可以混用的,在都是英文字母的时候str和unicode没有区别。

而Python3严格区分文本(str)和二进制数据(Bytes),文本总是Unicode,用str类型,二进制数据则用Bytes类型表示,这样严格的限制也让我们对如何使用它们有了清晰的认识,这是很棒的。

Python2 和 Python3 的区别

通过以下代码我们认识以下Python2和Python3的字符串混用情况:

# Python2中:In [1]: 'a' == u'a'Out[1]: True

In [2]: 'a' in u'a'Out[2]: True

In [3]: '编程' == u'编程'/usr/local/bin/ipython:1: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal#!/usr/bin/pythonOut[3]: False

In [4]: '编程' in u'编程'---------------------------------------------------------------------------UnicodeDecodeError Traceback (most recent call last)
<ipython-input-4-7b677a923254> in <module>()
----> 1 '编程' in u'编程'

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 0: ordinal not in range(128)

# Python3中:

In [1]: 'a' == b'a'Out[1]: False

In [2]: 'a' in b'a'---------------------------------------------------------------------------TypeError Traceback (most recent call last)
<ipython-input-10-ca907fd8856f> in <module>()
----> 1 'a' in b'a'

TypeError: a bytes-like object is required, not 'str'

以上代码可以看到,Python2中str和Unicode在都是ASCII码时混用没区别,因为Unicode的ASCII区域的值跟str的ASCII是一样的;而对应非ASCII区域(比如中文),二者又不一样了。

可以看到Python2抛出了Unicode Decode Error的异常,相信这也是很多人处理文本时遇到过的错误;‘编程'在str类型时长度是6,而在Unicode时是2。不同字符的不同表现,让Python2的str和Unicode显得扑朔迷离。

在Python3中,严格区分了str和Bytes,不同类型之间操作就会抛出Type Error的异常。

上面用示例阐述了Python2和Python3中字符串的不同,下面主要讲Python3中的字符串。

str和bytes之间的转换

一图胜千言:

浅析Python 3 字符串中的 STR 和 Bytes 有什么区别

str和bytes的相互转换

str.encode(‘encoding') -> bytes
bytes.decode(‘encoding') -> str

Encoding指的是具体的编码规则的名称,对于中文来说,它可以是这些值: ‘utf-8', ‘gb2312', ‘gbk', ‘big5' 等等。

不知道你有没有注意到上图中str矩形要比Bytes矩形短,表示同样的内容,str的长度要小于或等于Bytes的长度,你可以考虑一下原因(参考Unicode、UTF-8的编码规则)。

下面看看具体代码理解一下str和Bytes的相互转换:

In [16]: a = 'T恤'In [17]: a
Out[17]: 'T恤'In [18]: len(a)
Out[18]: 2In [19]: b = a.encode('utf8')

In [20]: b
Out[20]: b'T\xe6\x81\xa4'In [21]: a == b
Out[21]: FalseIn [22]: c = a.encode('gbk')

In [23]: c
Out[23]: b'T\xd0\xf4'In [24]: b == c
Out[24]: FalseIn [25]: a == c
Out[25]: False

上面str和Bytes之间的转换是针对文本内容的,要是其它二进制内容(比如,图片)时,Bytes就不能decode成str了,看以下代码的异常:

In [29]: img = open('str-bytes.jpg', 'rb').read()

In [30]: type(img)
Out[30]: bytes

In [31]: img.decode('utf8')
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
<ipython-input-31-c9e28f45be95> in <module>()----> 1 img.decode('utf8')UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

因为图片中的二进制数据不符合文本数据的UTF-8编码规则。

上面获得图片数据时,我们用到了open()来读取文件,文件存储的无非是文本和二进制这两种格式,读写文件时也有分清楚编码:

In [32]: open('z.txt', 'w').write('T恤')
Out[32]: 2In [33]: open('z.txt', 'w').write(img)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-33-4a88980b3a54> in <module>()
----> 1 open('z.txt', 'w').write(img)

TypeError: write() argument must be str, not bytes

In [34]: open('z.txt', 'wb').write(img)
Out[34]: 12147

读写二进制数据(如图片)时,要加'rb'参数,b代码Binary(二进制)。读写文本数据时,一般加'b',open()会自动转换Bytes到str。

总结一下

Python3里面的str是在内存中对文本数据进行使用的,Bytes是对二进制数据使用的。

str可以encode为Bytes,但是Bytes不一定可以decode为str。实际上Bytes.decode(‘latin1')可以称为str,也就是说decode使用的编码决定了decode()的成败,同样的,UTF-8编码的Bytes字符串用GBK去decode()也会出错。

Bytes一般来自网络读取的数据、从二进制文件(图片等)读取的数据、以二进制模式读取的文本文件(.txt, .html, .py, .cpp等)。

总结

以上所述是小编给大家介绍的Python 3 字符串中的 STR 和 Bytes 有什么区别,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Python 相关文章推荐
详解Python中的变量及其命名和打印
Mar 11 Python
Python正则表达式实现截取成对括号的方法
Jan 06 Python
numpy中loadtxt 的用法详解
Aug 03 Python
Python sorted函数详解(高级篇)
Sep 18 Python
Python读取stdin方法实例
May 24 Python
解决Pyinstaller 打包exe文件 取消dos窗口(黑框框)的问题
Jun 21 Python
Python基于Opencv来快速实现人脸识别过程详解(完整版)
Jul 11 Python
对Python 中矩阵或者数组相减的法则详解
Aug 26 Python
Python pathlib模块使用方法及实例解析
Oct 05 Python
PyQt5 QThread倒计时功能的实现代码
Apr 02 Python
详解Python描述符的工作原理
Jun 11 Python
pyqt5蒙版遮罩mask,setmask的使用
Jun 11 Python
Python中实例化class的执行顺序示例详解
Oct 14 #Python
Python读取Excel表格,并同时画折线图和柱状图的方法
Oct 14 #Python
对python3中pathlib库的Path类的使用详解
Oct 14 #Python
python使用numpy读取、保存txt数据的实例
Oct 14 #Python
Python读取txt某几列绘图的方法
Oct 14 #Python
python实现从文件中读取数据并绘制成 x y 轴图形的方法
Oct 14 #Python
python得到qq句柄,并显示在前台的方法
Oct 14 #Python
You might like
一些操作和快捷键的理解和讨论
2020/03/04 星际争霸
PHP+Mysql+Ajax实现淘宝客服或阿里旺旺聊天功能(前台页面)
2017/06/16 PHP
Laravel中七个非常有用但很少人知道的Carbon方法
2017/09/21 PHP
CentOS7系统搭建LAMP及更新PHP版本操作详解
2020/03/26 PHP
关于javascript 回调函数中变量作用域的讨论
2009/09/11 Javascript
JavaScript 学习笔记之操作符(续)
2015/01/14 Javascript
JavaScript实现Flash炫光波动特效
2015/05/14 Javascript
jQuery控制控件文本的长度的操作方法
2016/12/05 Javascript
jquery插件treegrid树状表格的使用方法详解(.Net平台)
2017/01/03 Javascript
jQuery实现页面滚动时智能浮动定位
2017/01/08 Javascript
vue2.0 keep-alive最佳实践
2017/07/06 Javascript
Bootstrap 模态对话框只加载一次 remote 数据的完美解决办法
2017/07/09 Javascript
underscore之Chaining_动力节点Java学院整理
2017/07/10 Javascript
web前端开发中常见的多列布局解决方案整理(一定要看)
2017/10/15 Javascript
浅谈Vuex的状态管理(全家桶)
2017/11/04 Javascript
详解JavaScript原生封装ajax请求和Jquery中的ajax请求
2019/02/14 jQuery
[07:40]DOTA2每周TOP10 精彩击杀集锦vol.4
2014/06/25 DOTA
python实现多线程采集的2个代码例子
2014/07/07 Python
python 示例分享---逻辑推理编程解决八皇后
2014/07/20 Python
使用PyV8在Python爬虫中执行js代码
2017/02/16 Python
django中的setting最佳配置小结
2017/11/21 Python
django中的HTML控件及参数传递方法
2018/03/20 Python
Python多叉树的构造及取出节点数据(treelib)的方法
2019/08/09 Python
pytorch 使用加载训练好的模型做inference
2020/02/20 Python
Pycharm创建文件时自动生成文件头注释(自定义设置作者日期)
2020/11/24 Python
canvas基础之图形验证码的示例
2018/01/02 HTML / CSS
中国茶叶、茶具一站式网上购物商城:醉品茶城
2018/07/03 全球购物
法律专业学生的自我评价
2014/02/07 职场文书
临床护理求职信
2014/04/26 职场文书
机电一体化专业毕业生自荐信
2014/06/19 职场文书
文案策划专业自荐信
2014/07/07 职场文书
村道德模范事迹材料
2014/08/28 职场文书
大四优秀党员个人民主评议
2014/09/19 职场文书
师德标兵事迹材料
2014/12/19 职场文书
python神经网络编程之手写数字识别
2021/05/08 Python
苹果的回收机器人可以通过拆解iPhone获取大量的金和铜并外公布了环境保护最新进展
2022/04/21 数码科技