zl程序教程

您现在的位置是:首页 >  其他

当前栏目

4.2 codecs--Codec注册管理和基类(2)

注册 管理 -- 4.2 codec 基类
2023-09-14 09:10:34 时间

codecs.register(search_function) 

注册一个codec的搜索函数。搜索函数要求能输入一个参数,编码器的名称以小写字母命名,如果成功找到返回CodecInfo对象,否则返回None

例子:

def add_cp65001_codec():

  try:

    codecs.lookup('cp65001')

  except LookupError:

    codecs.register(

        lambda name: name == 'cp65001' and codecs.lookup('utf-8') or None)

  return

 

codecs.open(filename, mode='r', encoding=None, errors='strict', buffering=1) 

用指定的模式mode来打开一个编码的文件filename,函数返回一个对文件进行编码或解码的流对象StreamReaderWriter。在对文件读写时可以使用编解码器encoding来进行处理,出错方式使用errors,数据缓存大小由buffering指定。

例子:

#python 3.4.3

import codecs

 

with codecs.open('d:/testcodecs.txt','a','utf-8') as f:

    f.write(u'中文')

 

 

with codecs.open('d:/testcodecs.txt','r','utf-8') as f:

    s = f.readlines()

    for line in s:

        print(line)

结果输出如下:

中文

从这个例子里可以看到,是把所有UNICODE内容按utf-8的编码来保存文件里,然后读取出来时,再按utf-8读取出来,并转换为UNICODE的编码方式显示出来。在这里没有明显看到有调用从UNICODE转换为utf-8的代码,从而实现了对开发人员有透明转换,提高代码安全性,杜绝开发人员忘记调用转换之后再使用相关文件内容的问题。

 

codecs.EncodedFile(file, data_encoding, file_encoding=None, errors='strict') 

返回一个StreamRecoder对象,主要提供一个透明转换两种编码的机制。当数据将要写文件时,要先经过data_encoding进行解码,接着进行file_encoding编码,最后把数据写入到文件。当要从文件读取数据时,先经过file_encoding进行解码,接着进行data_encoding编码,最后把数据交给使用者。

如果file_encoding不存在,默认是使用data_encoding来替换。

errors是错误的处理方式,默认是strict处理方式,如果不能处理会抛出异常ValueError

例子:

#python 3.4.3

import codecs

 

f_in   =   open('d:/abc1.txt',   'wb')

f_in.write('中文'.encode('utf_16'))

f_in.seek(0)

f_in.close()

 

f_in   =   open('d:/abc1.txt',   'rb')

f_out   =   open('d:/abc1_tmp.txt',   'wb')   

    

result_f   =   codecs.EncodedFile(f_in,   'gbk',   'utf16')   

for   chars   in   result_f:   

    f_out.write(chars)   

    

f_in.close()   

f_out.close()  

在这个例子里,先创建一个文件d:/abc1.txt,使用utf_16编码写进去。接着打开这个文件d:/abc1.txt,采用codecs.EncodedFile作为转换,把编码从utf_16读取出来,转换为gbk编码,然后把数据写到第二个文件d:/abc1_tmp.txt里,这时在第二个文件里就是gbk编码保存的文本了。

 

codecs.iterencode(iterator, encoding, errors='strict', **kwargs)

codecs.iterdecode(iterator, encoding, errors='strict', **kwargs) 

对迭代器iterator进行编码和解码,同时返回新的迭代器。这两个都是产生式函数。

例子:

#python 3.4.3

import codecs

import csv

import io

 

#写入一个CSV文件

io.open('d:/csv_test.csv', 'w', encoding='utf16').write(u'''\

    \t中国\t深圳\t深圳蔡

    ''')

 

#读取

def row_decode(reader, encoding='utf8'):

    for row in reader:

        yield [col for col in row]

 

 

with io.open('d:/csv_test.csv', encoding='utf16') as f:

    wrapped = codecs.iterencode(f, 'utf8')

    de = codecs.iterdecode(wrapped, 'utf8')

    reader = csv.reader(de, delimiter='\t')

    for row in row_decode(reader):

        print(row)

结果输出如下:

['    ', '中国', '深圳', '深圳蔡']

['    ']

在这个例子里,先保存一份csv的数据,然后打开这份文件进行读取,使用codecs.iterencode对文件对象进行包装,也即是使用utf8进行编码,接着又使用codecs.iterdecode对编码的包装器进行解码。最后对文件进行遍历并输出。

 

写入文件头里标记不同编码的常量byte order marks (BOMs)

codecs.BOM 

默认的BOM

 

codecs.BOM_BE 

大端格式的BOM

 

codecs.BOM_LE 

小端格式的BOM

 

codecs.BOM_UTF8 

UTF8BOM

 

codecs.BOM_UTF16 

UTF16BOM

 

codecs.BOM_UTF16_BE 

UTF16的大端的BOM

 

codecs.BOM_UTF16_LE 

UTF16的小端的BOM

 

codecs.BOM_UTF32 

UTF32默认的BOM

 

codecs.BOM_UTF32_BE 

UTF32的大端的BOM

 

codecs.BOM_UTF32_LE 

UTF32的小端的BOM

 

例子:

#python 3.4.3

import codecs

 

print(codecs.BOM)

print(codecs.BOM_BE)

print(codecs.BOM_LE)

print(codecs.BOM_UTF8)

 

print(codecs.BOM_UTF16)

print(codecs.BOM_UTF16_BE)

print(codecs.BOM_UTF16_LE)

print(codecs.BOM_UTF32)

 

print(codecs.BOM_UTF32_BE) 

print(codecs.BOM_UTF32_LE)

结果输出如下:

b'\xff\xfe'

b'\xfe\xff'

b'\xff\xfe'

b'\xef\xbb\xbf'

b'\xff\xfe'

b'\xfe\xff'

b'\xff\xfe'

b'\xff\xfe\x00\x00'

b'\x00\x00\xfe\xff'

b'\xff\xfe\x00\x00'



蔡军生  QQ:9073204  深圳