Python的bytes和str理解,以及解码编码问题。

 

尝试将ascii文件转换成utf-8的编码格式.Python3有两种表示字符序列的类型:bytes和str。个人理解是,bytes是计算机能够识别的数据类型,然后str是Unicode字符,即是人比较容易理解的字符类型。

以下代码包含在debug.py文件中:

def main():
    pass
 
if __name__ == '__main__':
    main()

 以bytes读取该文件,并通过 chardet.detect() 方法查看它的编码方式,并输出bytes格式(二进制数据)的字符串:

# debug.py的编码格式应该是Ascii的,然后转换成utf-8的格式

import chardet
import os

path = 'debug.py'

with open(path,'rb') as f:
     data_bytes = f.read()  #读取文件的二进制数据(bytes)
print(chardet.detect(data_bytes)['encoding'])#输出debug.py的编码方式
print(data_bytes)
print(type(data_bytes))

代码运行的结果如下:

ascii
b"def main():\r\n    pass\r\n \r\nif __name__ == '__main__':\r\n    main()\r\n"
<class 'bytes'>

由此可见,文件编码方式是Ascii,debug.py中的空格、换行等也会以字符的形式展现,如果有中文的话,中文会以十六进制的方式呈现,比如说“你好”(\xe4\xbd\xa0\xe5\xa5\xbd)。如果以'r'模式读取文件,结果又是怎样的呢?

def main():
    pass
 
if __name__ == '__main__':
    main()

没错,跟我们开头写进去的代码是一样的,这时候返回的结果是str形式的字符串。需要注意的是,chardet.detect()只能对bytes类型的字符串使用,否则会报错。

str和bytes之间的转换,需要用到解码和编码这两个概念。以下内容根据个人理解所写,如有出错,欢迎指出。

编码(encode)即是将我们所用str(一般来说,我们写的字符串都是str格式的,作为人类,我觉得还是str容易写点)以某一种编码方式转成机器能读懂的二进制数据格式(bytes)。解码(decode)则是相反的过程。

bytes --> decode('输入源文件的编码方式')--> str
str --> encode('以某种编码方式') --> bytes

注意解码和编码使用的对象。这个过程可以理解成上世纪发电报的过程。人们将通用语言,以某一种方式(比如说摩斯密码)转成另外一种格式,发送给对方,对方接收之后,必须再反过来转成通用语言才能理解。这就是编码和解码的过程。

言归正传,如果要转换文件的编码方式,那么就需要一个中间媒介。纵使编码方式不同,可能bytes对象会有所不同,但我们的通用语言却都是一致的。思路便是读取文件的bytes对象,然后解码成str,再以想要的编码方式(一般是utf-8)编码成bytes,最终写入原来的文件。

data_str = data_bytes.decode(chardet.detect(data_bytes)['encoding'])
print(data_str)

上面得到的结果,仍然是和以‘r’读取的方式一样。为什么不直接读取str?读取文件都有默认的编码方式,所以有可能直接读取str会因为编码方式的不同而出现乱码。

#以utf-8的编码格式转成bytes
data_utf = data_str.encode('utf-8')

通过这个指令可以得到utf-8编码的bytes,再将它写入覆盖源文件,即可完成转码。

 

作者注:编译器会将没有中文的py脚本识别为Ascii,所以通过转码最终也是会被识别成Ascii,不知道是不是系统为了节省内存空间的机制。这个目前我还没有找到解决方法,有解决方法再回来更改,望谅解。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值