【Python】使用codecs模块进行文件操作及消除文件中的BOM

7人阅读 评论(0) 收藏 举报
分类:

前言

此前遇到过UTF8格式的文件有无BOM的导致的问题,最近在做自动化测试,读写配置文件时又遇到类似的问题,和此前一样,又是折腾了挺久之后,通过工具比较才知道原因。

image

两次在一个问题上面栽更头,就在想有没有一个一劳永逸的方法避免这个问题,或者能做到检测,不用到最后借助Beyond Compare进行16进制比较。

之前的博客中UTF8格式的文件有无BOM做了比较详细的说明,有兴趣的可以看看:
UTF-8文件的Unicode签名BOM(Byte Order Mark)问题记录(EF BB BF)

Python codecs

此前很少使用codecs,查阅了相关资料知道这个是一个好东西。

比如说当我们有数据要保存的时候,大多数时候会选择保存到TXT中,当然数据量大的时候,保存到数据库还是比较方便,然后在网络传输的时候需要序列号、json化。

而我们操作txt平常用得最多的就是open内置函数,或者file这个工厂函数,两者效果基本一样。

但是我们用open方法打开文件有时候会有一些问题,因为open打开文件只能写入str类型,而不会管字符串是什么编码方式。

例如这样是可以的,示例:

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

但是有时候我们爬虫或者其他方式得到一些数据写入文件时会有编码不统一的问题,此时写入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...)

其实Python提供了更简单的做法,那就是今天的主角codecs.open,示例:

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

没有报错,写入成功!

其实Python对多国语言的处理是支持的很好的,它可以处理当下任意编码的字符。

有一点需要清楚的是,当python要做编码转换的时候,会借助于内部的编码,转换过程是这样的:

原有编码 -> 内部编码 -> 目的编码

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

检测及消除BOM

然后继续我们今天的另外一个主题,怎么样消除UTF-8文件中的名BOM(Byte Order Mark),十六进制编码(EF BB BF),博主的方法有些取巧但是也比较高效,主要用到了codecs的函数BOM_UTF8,如果发现BOM_UTF8,则直接改写文件内容。

示例代码:

import codecs

with open(config_path) as source_file:
    data = source_file.read()

   # remove BOM
   if data[:3] == codecs.BOM_UTF8:  # 判断是否为带BOM文件
        data = data[3:]
        with codecs.open(config_path) as dest_file:
            dest_file.write(data)

相关读写模式

codecs有如下的读写模式,和open用法基本一致。

模式 描述
r 仅读,待打开的文件必须存在
w 仅写,若文件已存在,内容将先被清空
a 仅写,若文件已存在,内容不会清空
r+ 读写,待打开的文件必须存在
w+ 读写,若文件已存在,内容将先被清空
a+ 读写,若文件已存在,内容不会清空
rb 仅读,二进制,待打开的文件必须存在
wb 仅写,二进制,若文件已存在,内容将先被清空
ab 仅写,二进制,若文件已存在,内容不会清空
r+b 读写,二进制,待打开的文件必须存在
w+b 读写,二进制,若文件已存在,内容将先被清空
a+b 读写,二进制,若文件已存在,内容不会清空

相关资料:

https://www.cnblogs.com/buptldf/p/4805879.html

https://blog.csdn.net/chenyxh2005/article/details/72465758

https://blog.csdn.net/zhaoweikid/article/details/1642015

查看评论

python使用codecs模块进行文件操作-读写中英文字符

由于python中默认的编码是ascii,如果直接使用open方法得到文件对象然后进行文件的读写,都将无法使用包含中文字符(以及其他非ascii码字符),因此建议使用utf-8编码。 使用方法 ...
  • chenyxh2005
  • chenyxh2005
  • 2017-05-18 13:30:33
  • 7173

python的IO,以及codecs模块

读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。 读文件 打开一个文件,读取后应该close(),为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... ...
  • zhihaoma
  • zhihaoma
  • 2016-07-18 20:54:11
  • 1967

【codecs.BOM】使用Python程序输出csv格式数据

这些天做一个数据处理的任务: 要求是输出一个csv格式的文件。 每次用NotePad++打开都正常,一用excel打开就一万个乱码, 好不容易乱码没了,用作分隔符的逗号也进单元格去了(变成单列了) ...
  • okcd00
  • okcd00
  • 2016-03-17 18:04:30
  • 2390

python模块之codecs: 自然语言编码转换

    python对多国语言的处理是支持的很好的,它可以处理现在任意编码的字符,这里深入的研究一下python对多种不同语言的处理。    有一点需要清楚的是,当python要做编码转换的时候,会借...
  • zhaoweikid
  • zhaoweikid
  • 2007-06-07 11:45:00
  • 35487

使用codecs模块,在Python中完成字符编码

字符的编码是按照某种规则在单字节字符和多字节字符之间进行转换的某种方法。从单字节到多字节叫做decoding,从多字节到单字节叫做encoding。在这些规则中经常用到的无非是UTF-8和GB2312...
  • HMSIWTV
  • HMSIWTV
  • 2014-03-03 21:30:41
  • 5500

python之decode、encode及codecs模块

直接贴地址 :http://www.cnblogs.com/hester/p/5465338.html
  • dedecms8
  • dedecms8
  • 2017-07-09 15:09:47
  • 293

python模块之codecs

  python对多国语言的处理是支持的很好的,它可以处理现在任意编码的字符,这里深入的研究一下python对多种不同语言的处理。    有一点需要清楚的是,当python要做编码转换的时候,会借...
  • zzjjzzgggg
  • zzjjzzgggg
  • 2008-03-28 15:37:00
  • 750

Python模块之codecs

Python对多国语言的处理是支持的很好的,它可以处理现在任意编码的字符,这里深入的研究一下python对多种不同语言的处理。     有一点需要清楚的是,当python要做编码转换的时候,会借助于...
  • Xw_Classmate
  • Xw_Classmate
  • 2016-07-18 10:10:49
  • 1312

Python3 codecs库基本使用

编码与解码:用到的库codecs例子:>>>raw_string = codecs.encode("我能吞下玻璃而不伤害身体", "gb2312")>>> raw_string>>>b'\xce\xd...
  • sunlanchang
  • sunlanchang
  • 2016-09-06 08:51:13
  • 823

python学习笔记 --- 实现将文件转换编码为utf-8-sig(带BOM)

python学习笔记 --- 实现将文件转换编码为utf-8-sig(带BOM)
  • u012965373
  • u012965373
  • 2016-09-27 14:59:28
  • 1845
    个人资料
    持之以恒
    等级:
    访问量: 1572
    积分: 273
    排名: 10万+
    文章存档
    最新评论