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

简介: pythonunicodebytesstr编码首先需要说明一下,该篇文章是以python3为基础的,python2是否适合没有验证过。由于python编码问题确实比较多,文章篇幅可能较长,请耐心看完,绝对物超所值,何况还是免费的,只求转载的时候注明出处,谢谢!一、 简单的编码介绍平常我们可能听说过很多编码格式,如 ASCII码,Unicode,utf-8,gbk等等。
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。

python3编码问题终结者--还搞不懂你来找我 - marsggbo - 火星教教主-marsggbo
 

编码格式转换.png

二、老大难的文件操作

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

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

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

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

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

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

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

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

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

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

  • 还是文件读写操作

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

  • 1.最原始的方法。。。

  1. ways = ["utf-8","gbk","gb2312","ASCII","Unicode"
  2. for encoding in ways: 
  3. print(encoding) 
  4. try
  5. with codecs.open("test.csv","r",encoding=encoding) as f: 
  6. data = f.read() 
  7. print(type(data)) 
  8. break 
  9. except Exception as e: 
  10. pass 

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

  • 2.比较高端的方法

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

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

亲测得到的结果如下图

python3编码问题终结者--还搞不懂你来找我 - marsggbo - 火星教教主-marsggbo
 


4.png

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

  1. import chardet  
  2.  
  3. a = "你好" 
  4. print(type(a)) 
  5. chardet.detect(a) 
  6.  
  7. >>> 
  8. <class 'str'> 
  9. Traceback (most recent call last): 
  10. File "E:\Code\python\Flask\csv-mysql\test.py", line 63, in <module> 
  11. chardet.detect(a) 
  12. File "C:\Python35\lib\site-packages\chardet\__init__.py", line 25, in detect 
  13. raise ValueError('Expected a bytes object, not a unicode object'
  14. ValueError: Expected a bytes object, not a unicode object 

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

提出的建议是

使用codecs.open()打开文件

使用bytes方式访问文件,如rb和wb

使用chardet.detect()检测bytes类型文本的编码格式,然后再解码(decode)或者编码(encode)


End


目录
相关文章
|
7月前
|
存储 Python
Python文件编码概念详解
Python文件编码概念详解
61 1
|
3月前
|
Python
python第三方库-字符串编码工具 chardet 的使用(python3经典编程案例)
这篇文章介绍了如何使用Python的第三方库chardet来检测字符串的编码类型,包括ASCII、GBK、UTF-8和日文编码的检测示例。
144 6
|
3月前
|
Python
Python 中如何指定 open 编码为ANSI
Python 中如何指定 open 编码为ANSI
55 1
|
4月前
|
数据采集 开发工具 Python
海康威视工业相机SDK+Python+PyQt开发数据采集系统(支持软件触发、编码器触发)
该系统基于海康威视工业相机SDK,使用Python与PyQt开发,支持Gige与USB相机设备的搜索及双相机同时显示。系统提供软件触发与编码器触发模式,并可在数据采集过程中实时保存图像。此外,用户可以调节曝光时间和增益,并进行信息输入,这些信息将被保存至配置文件以便下次自动加载。参数调节与实时预览等功能进一步增强了系统的实用性。
224 1
|
4月前
|
开发者 Python
Python编码风格
Python编码风格
28 1
|
4月前
|
JSON 数据库 开发者
FastAPI入门指南:Python开发者必看——从零基础到精通,掌握FastAPI的全栈式Web开发流程,解锁高效编码的秘密!
【8月更文挑战第31天】在当今的Web开发领域,FastAPI迅速成为开发者的热门选择。本指南带领Python开发者快速入门FastAPI,涵盖环境搭建、基础代码、路径参数、请求体处理、数据库操作及异常处理等内容,帮助你轻松掌握这一高效Web框架。通过实践操作,你将学会构建高性能的Web应用,并为后续复杂项目打下坚实基础。
131 0
|
5月前
|
Python
11个提升Python列表编码效率的高级技巧
Python中关于列表的一些很酷的技巧
54 1
|
5月前
|
存储 缓存 Python
python中小数据池和编码
python中小数据池和编码
58 3
|
5月前
|
缓存 Java Unix
python中内存管理等10个编码习惯
【7月更文挑战第3天】本文涵盖了Python编程中的变量管理、模块导入、命令行参数、内存管理和面向对象设计的10个关键概念。
50 0
python中内存管理等10个编码习惯
|
6月前
|
自然语言处理 Python
Python编码问题
Python编码问题是指在处理文本时,由于编码不一致导致程序不能正确处理文本的问题。在Python中,编码问题主要有两种情况:文件编码问题和字符串编码问题。
67 7