You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Odia语言Python编解码报错问题咨询(含cp1252疑问)

Odia字符串编解码问题解析

先还原你遇到的场景,代码和报错如下:

b = "କାହିଁକି ଏଇଠି ଅଛୁ "
x = b.encode()
print(x)
m = x.decode()
print(m)

输出内容:

b'\xe0\xac\x95\xe0\xac\xbe\xe0\xac\xb9\xe0\xac\xbf\xe0\xac\x81\xe0\xac\x95\xe0\xac\xbf \xe0\xac\x8f\xe0\xac\x87\xe0\xac\xa0\xe0\xac\xbf \xe0\xac\x85\xe0\xac\x9b\xe0\xad\x81 '
Traceback (most recent call last):
  File "x:\Pythonxx36\Egod\expeppp.py", line 9, in <module>
    print(m)
File "C:\ProgramData\Miniconda3\envs\pygpu\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-6: character maps to <undefined>

问题1:为何同一编码文本解码时会报错?

其实你误会了——解码本身并没有报错,问题出在print(m)这一步。咱们拆解下整个流程:

  • 调用b.encode()时,Python3默认用UTF-8编码字符串,所以x是正确的UTF-8字节串;
  • 调用x.decode()时,同样默认用UTF-8解码,得到的m已经是完整的Odia Unicode字符串;
  • 报错是因为你的控制台(终端)默认使用CP1252编码,而CP1252不支持Odia字符,Python试图把Unicode字符串转换成CP1252字节输出时,找不到对应字符的映射关系,才抛出了编码错误。

简单说:编解码全程是正常的,只是输出到控制台时的编码不兼容导致了报错。你可以试试把m写入UTF-8编码的文件,会发现完全能正常保存和读取。

问题2:cp1252.py是什么?

CP1252是Windows系统常用的一种单字节字符编码,主要用来支持西欧语言(英语、法语、德语等),它只包含ASCII字符和少量扩展拉丁字符,完全不支持Odia这类非拉丁系的Unicode字符。

cp1252.py是Python标准库encodings目录下的模块,专门负责实现CP1252编码的转换逻辑——比如把Unicode字符映射成CP1252字节,或者反向解码。当Python需要用CP1252编码处理字符时,就会调用这个模块里的方法。

问题3:若Python现有编码均不支持Odia语言,如何创建新编码?(可选)

其实完全没必要折腾!UTF-8支持所有Unicode字符,而Odia字符本身就属于Unicode的Odia区块(U+0B00到U+0B7F),所以UTF-8能完美处理Odia字符串。你之前的问题只是控制台编码的问题,不是UTF-8不支持。

如果真的需要适配某种特殊旧格式、必须自定义编码,可以用Python的codecs模块注册自定义编码,实现自己的编码和解码函数,但这在你的场景里完全没必要。只要把控制台编码改成UTF-8,或者把内容写入UTF-8编码的文件,就能正常显示Odia字符了。


内容的提问来源于stack exchange,提问作者ASHu2

火山引擎 最新活动