聊聊Python 3 的字符串:str 和 bytes 的区别
Python2的字符串有两种:str 和 unicode,Python3的字符串也有两种:str 和 bytes。Python2 的 str 相当于 Python3 的bytes,而unicode相当于Python3的str。
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/python Out[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抛出了UnicodeDecodeError的异常,相信这也是很多人处理文本时遇到过的错误;‘编程’在str类型时长度是6,而在unicode时是2。不同字符的不同表现,让Python2的str和unicode显得扑朔迷离。
在Python3中,严格区分了str和bytes,不同类型之间操作就会抛出TypeError的异常。
上面用示例阐述了Python2和Python3中字符串的不同,下面主要讲Python3中的字符串。
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]: 2 In [19]: b = a.encode('utf8') In [20]: b Out[20]: b'T\xe6\x81\xa4' In [21]: a == b Out[21]: False In [22]: c = a.encode('gbk') In [23]: c Out[23]: b'T\xd0\xf4' In [24]: b == c Out[24]: False In [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]: 2 In [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教程。
版权申明:若没有特殊说明,文章皆是猿人学原创,没有猿人学授权,请勿以任何形式转载。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Python用ctypes调用动态库的方式使用科大讯飞语音识别
ctypes 是 Python 的一个模块,它提供了C语言相关的数据类型,可以方便的调用C语言编写的DLL(Windows 动态链接库)和so(Linux动态链接库)。科大讯飞的语音识别客户端SDK提供了Linux下的C语言SDK,却没有Python的。有了ctypes,我们就可以很轻松的用Python来使用科大讯飞的语音识别了。 通过LoadLibrary()函数加载动态库: xflib = ctypes.cdll.LoadLibrary('msc/libmsc.so') 在Python里面调用C函数时主要是注意参数的类型。语音识别的接口的具体参数可以参考其提供的文档,比如接口函数: const char* MSPAPI QISRSessionBegin( const char* grammarList, const char* params, int* errorCode ) 返回的是一个char指针作为sessionID以供后续接口作为参数使用,在Python里面要用ctypes.c_voidp类型: ret = ctypes.c_int() sessionId = ctypes...
- 下一篇
windows系统手动搭建PHP环境
Windows操作系统下手动搭建PHP环境,环境吧是以php5.6+MySQL5.6+Apache2.4版本的组合来搭建环境: windows系统手动搭建PHP环境 本文介绍的是本机Windows操作系统搭建PHP环境教程,如果是Windows下的云服务器可以参考官方文档:Windows实例通过IIS搭建PHP环境 - 阿里云,本文适合在本机PHP环境测试。 手动安装PHP环境比较麻烦,环境吧先帮大家梳理下: 版本搭配:php5.6+MySQL5.6+Apache2.4 大致流程概述:①下载PHP、MySQL和Apache三款软件;②安装MySQL数据库;③安装和配置Apache服务器;④配置PHP模块到Apache服务器上;⑤配置MySQL。以下详细流程就是按照这五个步骤: 一:下载PHP、MySQL和Apache三款软件 1、下载PHP5.6版本 下载地址:https://windows.php.net/download#php-5.6 下载注意事项: 本文是以Apache作为服务器环境,所以选择Thread Safe(线程安全)版本; 如果你的Windows是32位系统就选择x8...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Mario游戏-低调大师作品
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8