VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • Python3标准库:codecs字符串编码和解码(6)

)
  •  
  • all_encoded = b''.join(encoded)
  • print()
  • print('Total encoded length:', len(all_encoded))
  • print()
  •  
  • # Decode the byte string one byte at a time
  • decoder = codecs.getincrementaldecoder('bz2')()
  • decoded = []
  •  
  • print('Decoding:', end=' ')
  • for i, b in enumerate(all_encoded):
  • final = (i + 1) == len(text)
  • c = decoder.decode(bytes([b]), final)
  • if c:
  • print('\nDecoded : {} characters'.format(len(c)))
  • print('Decoding:', end=' ')
  • decoded.append(c)
  • else:
  • sys.stdout.write('.')
  • print()
  •  
  • restored = b''.join(decoded)
  •  
  • print()
  • print('Total uncompressed length:', len(restored))
  • 每次将数据传递到编码器或解码器时,其内部状态都会更新。状态一致时(按照codec的定义),会返回数据并重置状态。在此之前,encode()或decode()调用并不返回任何数据。传入最后一位数据时,参数final应当设置为True,这样codec就能知道需要刷新输出所有余下的缓冲数据。

    1.8 定义定制编码

    由于Python已经提供了大量标准codecs,所以应用一般不太可能需要定义定制的编码器或解码器。不过,如果确实有必要,codecs中的很多基类可以帮助你更容易的定义定制编码。

    第一步是了解编码描述的转换性质。这一节中的例子将使用一个“invertcaps”编码,它把大写字母转换为小写,把小写字母转换为大写。下面是一个编码函数的简单定义,它会对输入字符串完成这个转换。

    
    	
    1. import string
    2.  
    3. def invertcaps(text):
    4. """Return new string with the case of all letters switched.
    5. """
    6. return ''.join(
    7. c.upper() if c in string.ascii_lowercase
    8. else c.lower() if c in string.ascii_uppercase
    9. else c
    10. for c in text
    11. )
    12.  
    13. if __name__ == '__main__':
    14. print(invertcaps('ABCdef'))
    15. print(invertcaps('abcDEF'))

    在这里,编码器和解码器都是同一个函数(与ROT-13类似)。

    尽管很容易理解,但这个实现效率不高,特别是对于非常大的文本串。幸运的是,codecs包含一些辅助函数,可以创建基于字符映射(character map)的codecs,如invertcaps。字符映射编码由两个字典构成。编码映射(encoding map)将输入串的字符值转换为输出中的字节值,解码映射(decoding map)则相反。首先创建解码映射,然后使用make_encoding_map()把它转换为一个编码映射。C函数charmap_encode()和charmap_decode()可以使用这些映射高效的转换输入数据。 

    
    	
    1. import codecs
    2. import string
    3.  
    4. # Map every character to itself
    5. decoding_map = codecs.make_identity_dict(range(256))
    6.  
    7. # Make a list of pairs of ordinal values for the lower
    8. # and uppercase letters
    9. pairs = list(zip(
    10. [ord(c) for c in string.ascii_lowercase],
    11. [ord(c) for c in string.ascii_uppercase],
    12. ))
    13.  
    14. # Modify the mapping to convert upper to lower and
    15. # lower to upper.
    16. decoding_map.update({
    17. upper: lower
    18. for (lower, upper)
    19. in pairs
    20. })
    21. decoding_map.update({
    22. lower: upper
    23. for (lower, upper)
    24. in pairs
    25. })
    26.  
    27. # Create a separate encoding map.
    28. encoding_map = codecs.make_encoding_map(decoding_map)
    29.  
    30. if __name__ == '__main__':
    31. print(codecs.charmap_encode('abcDEF', 'strict',
    32. encoding_map))
    33. print(codecs.charmap_decode(b'abcDEF', 'strict',
    34. decoding_map))
    35. print(encoding_map == decoding_map)

    尽管invertcaps的编码和解码映射是一样的,但并不总是如此。有时会把对各输入字符编码为相同的输出字节,make_encoding_map()会检测这些情况,并把编码值替换为None,以标志编码为未定义。

    字符映射编码器和解码器支持前面介绍的所有标准错误处理方法,所以不需要做任何额外的工作来支持这部分API。 

    
    	
    1. import codecs
    2. import string
    3.  
    4. # Map every character to itself
    5. decoding_map = codecs.make_identity_dict(range
    
    相关教程