问题发现
在学习socket编程时,遇到这样一个报错,意思是需要一个字节流的对象,而不是str。
a bytes-like object is required, not 'str'
我们知道在网络传输中,数据是以二进制的方式进行传输的,报这个错大概就是你这个东西不是二进制,而是“文本”,我不能进行传输。
解决方案也很简单,只需要在传输的信息后面加上.decode("..."),就可以使用某种编码方式进行传输了。
当时越想越蒙,Python里的“文本”是什么格式,Python2和Python3貌似是什么不同来着,感觉自己的基本功太欠缺,编码方面的事情没有搞懂。
Python2和Python3
在网上的资料中,Python2的字符串有两种类型:str和unicode,str是属于字节流类型,默认的编码方式是ascii,所以Python2中脚本第二行,一般会写上用utf-8编码,否则中文及其它一些符号是不能显示的。
到了Python3字符串就只有unicode类型了,unicode是什么?
Unicode(中文:万国码、国际码、统一码、单一码)是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字。-来自维基百科
可以这样理解,unicode是一个非常大的表格,它对世界上的字符都进行了编码,每个字符都有自己的代号,可以查看这个链接,是中文的unicode编码。
那utf-8又是什么?首先unicode编码只是对字符进行了编码,比如令的编码是4EE4,但它并没有说这个字存储时怎么存,utf-8的意义就是规定了它的存储方式,再比如令存储为xe4xbbxa4,具体可以查看utf-8是以什么规则进行存储的。
在Python3中,编码方式就是utf-8了,我们的代码,文本文件操作时会以这种编码方式。
审视问题
回过头来看一下这个问题,我们就知道是怎么回事了。比如我们想传输一句话:你好,世界。这在Python中是以unicode方式进行存储,这样当然不能通过网络传输了,所以需要s.encode('utf8'),当然不写utf8,也是默认使用的utf8,这样我们的话就可以顺着网线传输过去,对方接收时,也用utf8进行解码就可以,即.decode('utf8')。如果我们发送的是纯英文,使用ascii编码就可以完成传输和接收的任务。
总结
到这里基本上就大致讨论完Python的编码方式了,在Windows和Linux上还有一些不同,所以最好显示指定编码方式和解码方式。
总而言之,一个unicode编码的字符有encode方法,你可以把它用任何格式进行编码;一个二进制类型的数据,你可以使用decode方法,通过相应的解码方式,去看到它的字符含义。