Python + PostgreSQL +奇怪的ascii = UTF8编码错误

Cla*_*diu 6 python postgresql unicode encoding utf-8

我有ascii字符串,其中包含"\x80"代表欧元符号的字符:

>>> print "\x80"
€
Run Code Online (Sandbox Code Playgroud)

将包含此字符的字符串数据插入数据库时​​,我得到:

psycopg2.DataError: invalid byte sequence for encoding "UTF8": 0x80
HINT:  This error can also happen if the byte sequence does not match the encodi
ng expected by the server, which is controlled by "client_encoding".
Run Code Online (Sandbox Code Playgroud)

我是一个unicode新手.如何将包含的字符串转换"\x80"为包含相同欧元符号的有效UTF-8?我已经打过电话.encode,并.decode在不同的字符串,但遇到错误:

>>> "\x80".encode("utf-8")
Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    "\x80".encode("utf-8")
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)

Joh*_*hin 12

问题始于错误的前提:

我有ascii字符串,其中包含字符"\ x80"来表示欧元符号.

ASCII字符在"\ x00"到"\ x7F"范围内.

先前已接受的现在删除的答案在两个严重误解下操作(1)locale ==编码(2)latin1编码将"\ x80"映射到欧元字符.

实际上,所有ISO-8859-x编码都将"\ x80"映射到U + 0080,这是C1控制字符之一,而不是欧元字符.这些编码中只有3个(x in(7,15,16))提供欧元字符,如"\ xA4".请参阅此维基百科文章.

您需要知道数据的编码方式.它创建的是什么机器?怎么样?它创建的区域设置(不一定是你的)可能会给你一个线索.

请注意,"我的数据以latin1编码"在那里有"邮件中的支票"和"我当然会在早上爱你".您的数据可能采用Windows平台上的cp125x编码之一进行编码.请注意,除了cp1251(Windows Cyrillic)之外的所有这些都将"\ x80"映射到欧元字符:

>>> ['\x80'.decode('cp125' + str(x), 'replace') for x in range(9)]
[u'\u20ac', u'\u0402', u'\u20ac', u'\u20ac', u'\u20ac', u'\u20ac', u'\u20ac', u'\u20ac', u'\u20ac']
Run Code Online (Sandbox Code Playgroud)

根据OP的评论进行更新

我正在从文件中读取这些数据,例如open(fname).read().它包含带有\ x80的字符串,表示欧元字符.它只是一个纯文本文件.它是由另一个程序生成的,但我不知道如何生成文本.什么是一个好的解决方案?我想我可以假设它为一个欧元字符输出"\ x80",这意味着我可以假设它用cp125x编码,其中该字符号为欧元.

这有点令人困惑:首先你说

它包含带有\ x80的字符串,表示欧元字符

但是后来你说

我想我可以假设它为欧元字符输出"\ x80"

请解释.

选择合适的cp125x编码:创建文件的位置(地理位置)?用什么语言写的是文字?除推定的欧元以外的任何字符值>"\ x7f"?如果是这样,他们使用了哪些以及它们的背景?

更新2如果您"不知道程序是如何编写的",那么您和我们都不能就是否总是使用"\ x80"表示欧元字符.虽然这样做会带来巨大的愚蠢,但不能排除它.

如果文本是用英语写的和/或是在美国写的,和/或是在Windows平台上写的,那么可以合理地确定这cp1252是要走的路......直到你得到相反的证据,在这种情况下,您需要自己猜测编码或回答(什么语言,什么地方)问题.