IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    caimouse发表于 2015-10-31 20:58:26
    love 0

    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 

    UTF8的BOM。

     

    codecs.BOM_UTF16 

    UTF16的BOM。

     

    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  深圳



沪ICP备19023445号-2号
友情链接