【问题标题】:Custom Python Charmap Codec自定义 Python Charmap 编解码器
【发布时间】:2019-05-27 21:52:36
【问题描述】:

我正在尝试编写自定义 Python 编解码器。这是一个简短的例子:

import codecs

class TestCodec(codecs.Codec):
    def encode(self, input_, errors='strict'):
        return codecs.charmap_encode(input_, errors, {
            'a': 0x01,
            'b': 0x02,
            'c': 0x03,
        })

    def decode(self, input_, errors='strict'):
        return codecs.charmap_decode(input_, errors, {
            0x01: 'a',
            0x02: 'b',
            0x03: 'c',
        })

def lookup(name):
    if name != 'test':
        return None
    return codecs.CodecInfo(
        name='test',
        encode=TestCodec().encode,
        decode=TestCodec().decode,
    )

codecs.register(lookup)
print(b'\x01\x02\x03'.decode('test'))
print('abc'.encode('test'))

解码有效,但编码抛出异常:

$ python3 codectest.py
abc
Traceback (most recent call last):
  File "codectest.py", line 29, in <module>
    print('abc'.encode('test'))
  File "codectest.py", line 8, in encode
    'c': 0x03,
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-2:
character maps to <undefined>

知道如何正确使用charmap_encode吗?

【问题讨论】:

    标签: python encoding character-encoding


    【解决方案1】:

    https://docs.python.org/3/library/codecs.html#encodings-and-unicode(第三段):

    还有另一组编码(所谓的charmap编码)选择所有Unicode代码点的不同子集,以及这些代码点如何映射到字节0x0-0xff。要查看这是如何完成的,只需打开例如encodings/cp1252.py(这是一种主要用于 Windows 的编码)。有一个包含 256 个字符的字符串常量,可以显示哪个字符映射到哪个字节值。

    根据提示查看 encodings/cp1252.py,并查看以下代码:

    import codecs
    
    class TestCodec(codecs.Codec):
        def encode(self, input_, errors='strict'):
            return codecs.charmap_encode(input_, errors, encoding_table)
    
        def decode(self, input_, errors='strict'):
            return codecs.charmap_decode(input_, errors, decoding_table)
    
    def lookup(name):
        if name != 'test':
            return None
        return codecs.CodecInfo(
            name='test',
            encode=TestCodec().encode,
            decode=TestCodec().decode,
        )
    
    decoding_table = (
        'z'
        'a'
        'b'
        'c'
    )    
    encoding_table=codecs.charmap_build(decoding_table)
    codecs.register(lookup)
    
    ### --- following is test/debug code
    print(ascii(encoding_table))
    
    print(b'\x01\x02\x03'.decode('test'))
    foo = 'abc'.encode('test')
    print(ascii(foo))
    

    输出:

    {97: 1, 122: 0, 99: 3, 98: 2}
    abc
    b'\x01\x02\x03'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      相关资源
      最近更新 更多