如何在Python 2.6中添加新的编码?
又遇到一个编码问题,我正在处理一个使用IBM870编码的IBM大型机,而这个编码在Python或者其他任何地方都不被支持。
幸运的是,有位天才程序员写了一个脚本,可以为Python生成合适的编码定义,这些定义是基于在FileFormat.info上找到的字符列表。
使用的字符列表可以在这里找到:IBM870字符列表
生成的编码可以在这里查看:cp870.py
这个系统是运行在RHEL 6.3上的,使用的是Python 2.6:
Python 2.6.6 (r266:84292, Aug 28 2012, 10:55:56)
[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2
cp870.py文件放在:
/usr/lib64/python2.6/encodings/
以下条目已被添加到:
/usr/lib64/python2.6/encodings/aliases.py
# cp870 codec
'870' : 'cp870',
'csibm870' : 'cp870',
'ibm870' : 'cp870',
别名被正确解析,如这里所示(感谢这个回答):
>>> from encodings.aliases import aliases
>>> def find(q):
... return [(k,v) for k, v in aliases.items() if q in k or q in v]
...
>>> find('870')
[('ibm870', 'cp870'), ('870', 'cp870'), ('csibm870', 'cp870')]
>>> find('cp870')
[('ibm870', 'cp870'), ('870', 'cp870'), ('csibm870', 'cp870')]
>>> find('ibm870')
[('ibm870', 'cp870'), ('csibm870', 'cp870')]
当我尝试对一些字符使用encode()时,结果并没有按预期工作:
>>> 'c'.encode('cp870')
'\x83'
>>> 'č'.encode('cp870')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.6/encodings/cp870.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 0: ordinal not in range(128)
根据cp870.py,'\x83'应该是这样的:
u'\x83' # 0x23 -> NO BREAK HERE (U+0083)
由于我对Python还是个新手,能否请教一下,还需要什么才能让Python正确加载和使用这个编码?
1 个回答
3
在Python 2.x中,Unicode字符串需要加上u或U的前缀。如果没有这个前缀,字符串就被认为是ASCII编码(或者其他8位编码)。
另外,Python默认你输入的内容是ASCII编码的(虽然你可以设置其他编码)。所以,当你在引号里放入一个非ASCII字符时,解释器会尝试把它当作ASCII来解码,这就会导致你看到的错误。
因此,你需要加上u前缀,并使用转义序列来指定这个字符:
U'\x83'.encode('cp870')