专栏首页AutoML(自动机器学习)python3编码问题终结者--还搞不懂你来找我

python3编码问题终结者--还搞不懂你来找我

python

unicode

bytes

str

编码

首先需要说明一下,该篇文章是以python3为基础的,python2是否适合没有验证过。 由于python编码问题确实比较多,文章篇幅可能较长,请耐心看完,绝对物超所值,何况还是免费的,只求转载的时候注明出处,谢谢!

一、 简单的编码介绍

平常我们可能听说过很多编码格式,如 ASCII码,Unicode,utf-8,gbk等等。为了不让文章臃肿,所以在这不再赘述,如想了解,请跳转到这个链接。 各种字符编码介绍

但是py3里,只有 unicode编码格式 的字节串才能叫作str。 其他编码格式的统统都叫bytes,如:gbk,utf-8,gb2312…………

在py3中,Unicode编码就像是一个枢纽,例如gbk的格式要想转化成utf-8,那么必须先转化成Unicode,然后再从Unicode转化成utf-8。

编码格式转换.png

二、老大难的文件操作

python各种各样的扩展卡确实给我们带来了极大的方便,但是对于初学者而言,编码问题却一而再再而三的出现,尤其以文件操作最为明显(反正我是这样的) 接下来将主要介绍文件读写操作和文件编码方式检测的方法。

  • 文件读写:open还是 codecs.open?

python读写文件估计大家都用open内置函数,但是用open方法打开会有一些问题。open打开文件只能写入str类型,不管字符串是什么编码方式。例如

>>> fr = open('test.txt','a') 
>>> line1 = "我爱祖国" 
>>> fr.write(line1) 

这样是完全可以的。但是有时候我们爬虫或者其他方式得到一些数据写入文件时会有编码不统一的问题,所以就一般都统一转换为unicode。此时写入open方式打开的文件就有问题了。例如

>>> line2 = u'我爱祖国'  
>>> fr.write(line2) 
 
Traceback (most recent call last): 
  File "<pyshell#4>", line 1, in <module> 
    fr.write(line2) 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-11: ordinal not in range(128) 
>>> 

怎么办,我们可以将上面的line2编码成str类型,但是太麻烦。我们要把得到的东西先decode为unicode再encode为str。。。 input文件(gbk, utf-8...) ----decode-----> unicode -------encode------> output文件(gbk, utf-8...)

代替这繁琐的操作就是codecs.open,例如

>>> import codecs 
>>> fw = codecs.open('test1.txt','a','utf-8') 
>>> fw.write(line2) 
>>> 

不会报错,说明写入成功。这种方法可以指定一个编码打开文件,使用这个方法打开的文件读取返回的将是unicode。写入时,如果参数 是unicode,则使用open()时指定的编码进行编码后写入;如果是str,则先根据源代码文件声明的字符编码,解码成unicode后再进行前述 操作。相对内置的open()来说,这个方法比较不容易在编码上出现问题。

  • 还是文件读写操作

上文中介绍的codecs.open()方法虽然明显比open要方便好用很多,但是使用这个函数的前提是我们需要知道文件的编码方式,但是事实是我们大多数情况下不知道文件的编码方式,所以一下给出两种解决办法。

  • 1.最原始的方法。。。
ways = ["utf-8","gbk","gb2312","ASCII","Unicode"] 
for encoding in ways: 
    print(encoding) 
 try: 
 with codecs.open("test.csv","r",encoding=encoding) as f: 
            data = f.read() 
            print(type(data)) 
 break 
 except Exception as e: 
 pass 

将python中常用的编码方式用list表示,然后用for循环逐一带入检验。由于utf-8和gbk用的较多,所以建议放在list的最前面。 一旦文件操作成功,则break,跳出循环。

  • 2.比较高端的方法

可以以bytes的形式对文件进行操作,这样即使不知道文件的编码方式也同样可以进行读写操作了,但是在最后需要进行decode或者encode。 如果对decode和encode不了解,请阅读这篇文章python编码问题之"encode"&"decode"

with codecs.open("test.csv","rb") as f: 
    data = f.read() 
    print(type(data)) 
    encodeInfo = chardet.detect(data) 
    print(data.decode(encodeInfo["encoding"])) 

亲测得到的结果如下图

4.png

解释一下上面的代码中的chardet.detect() chardet是一个python3自带的库,用于检测文本的编码方式,他会返回一个字典,格式是{"encoding" : "xxx", "confidence" :" xxx"}但是注意它一般只能检测bytes类型的编码格式,比如

import chardet  
 
a = "你好" 
print(type(a)) 
chardet.detect(a) 
 
>>> 
<class 'str'> 
Traceback (most recent call last): 
  File "E:\Code\python\Flask\csv-mysql\test.py", line 63, in <module> 
    chardet.detect(a) 
  File "C:\Python35\lib\site-packages\chardet\__init__.py", line 25, in detect 
 raise ValueError('Expected a bytes object, not a unicode object') 
ValueError: Expected a bytes object, not a unicode object 

总结一下: 本文一方面简单介绍了python的编码情况,另一方面介绍了文件操作中会遇到了问题以及解决的办法。

提出的建议是

  • 使用codecs.open()打开文件
  • 使用bytes方式访问文件,如rb和wb
  • 使用chardet.detect()检测bytes类型文本的编码格式,然后再解码(decode)或者编码(encode)

End

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • python编码问题之\"encode\"&\"decode\"

    python encode decode 编码 decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode(‘gb2312’),表...

    marsggbo
  • Pytorch--Dropout笔记

    dropout常常用于抑制过拟合,pytorch也提供了很方便的函数。但是经常不知道dropout的参数p是什么意思。在TensorFlow中p叫做keep_p...

    marsggbo
  • Pytorch里的CrossEntropyLoss详解

    首先要知道上面提到的这些函数一部分是来自于torch.nn,而另一部分则来自于torch.nn.functional(常缩写为F)。二者函数的区别可参见 知乎:...

    marsggbo
  • Build Castles(构建城堡) 原

    根据给出的数组,因为有重复的值,我首先想到的是将给出的数组进行一次过滤和处理,去掉重复的值。

    HoneyMoose
  • 0623-6.2.0-如何在CDH中安装CFM

    2019年4月15日,Cloudera在其官网宣布GA两款新的产品Cloudera Flow Management和Cloudera Edge Manageme...

    Fayson
  • 手动实现AJAX

    XMLHttpRequest对象进行HTTP请求前必须通过open初始化,open接受五个参数,分别为请求方法、请求链接、异步标识、账号和密码用以服务端验证

    WindrunnerMax
  • c++文件操作之文本文件-读文件

    绝命生
  • C++ N叉树的实现

    最近一个项目需要使用多叉树结构来存储数据,但是基于平时学习的都是二叉树的结构,以及网上都是二叉树为基础来进行学习,所以今天实现一个多叉树的数据结构。

    于小勇
  • Spring Cloud构建微服务架构:服务容错保护(Hystrix断路器)【Dalston版】

    前言 在前两篇Spring Cloud构建微服务架构:服务容错保护(Hystrix服务降级)【Dalston版】和Spring Cloud构建微服务架构:服务容...

    程序猿DD
  • java练习本(2019-07-23)

    “ To love and win is the best thing. To love and lose, the next best.”

    微笑的小小刀

扫码关注云+社区

领取腾讯云代金券