【问题标题】:Python 2 socket and string codingPython 2 套接字和字符串编码
【发布时间】:2012-03-17 10:58:58
【问题描述】:

我正在将 utf-8 格式的文件读入 unicode,但没有收到任何错误。

try:
        f = codecs.open(fil_name, "r","utf-8")
        f_str = f.read()

即字符串f_str在“unicode”中 稍后在程序中,我必须将 f_str 中的 (u) 字符串发送到套接字。我正在尝试将字符串转换回“utf-8”。

usock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
usock.connect(("xxx server", 123))
usock.send("TEXT %s\nENDQ\n" % f_str.replace("\n", " ").encode("utf-8"))

这里我收到一条错误消息:

usock.send("TEXT %s\nENDQ\n" % text.replace("\n", " ").encode("utf-8"))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 41: ordinal not in range(128)

在我的文本中,我的字符不能用纯 ASCII (äö..) 编码,但 utf-8 或 latin-1 没有问题。 为什么我收到此错误?我没有使用 ASCII,我使用的是 unicode/utf-8???

【问题讨论】:

    标签: python sockets unicode


    【解决方案1】:

    您的字符串文字是一个字节字符串。当您尝试插入时,Python 将隐式尝试使用默认编码 (ascii) 转换为字节字符串。

    有几种方法可以解决此问题。一种是只使用 Python 3。;-)

    如果您使用的是 Python 2,请将以下内容放在源文件的顶部:

    from __future__ import unicode_literals
    

    那么你的文字也将是 unicode。

    你也可以在字符串前面加上'u'。

    该行的另一个问题是优先级。 '%s' 格式操作是在右侧完成后尝试使用 ascii 编解码器将您的 unicode 隐式转换为字符串。

    所以,试试这个:

    (u"TEXT %s\nENDQ\n" % f_str.replace(u"\n", u" ")).encode("utf-8")
    

    【讨论】:

    • 谢谢基思,问题是您所说的操作的优先级。括号解决了它
    【解决方案2】:

    从检查明显的 python unicode 清单开始:

    1. -*- encoding:utf-8 -*- 放在每个源文件的顶部
    2. 检查文本文件编码是否为 utf-8(大多数默认为 ascii 1255)

    还有

    如果它已经是 unicode,为什么还需要编码('utf-8')?如果您不这样做,您会收到什么错误消息?

    您是否尝试将 f_str 显式声明为 unicode: like

    f_str=unicode(f_str)
    

    还可以尝试打印 f_str 并检查您之前是否得到了正确的结果。也许这是数据的问题

    【讨论】:

    • 我正在填写您所说的第 1 项,并且文件肯定是 utf-8 格式。我可以使用 codecs.open(..."utf-8") 读取数据,确保将数据转换为 unicode。我尝试打印 f_str 并且打印正确。
    • 如果我删除编码(“utf-8”),我会收到类似的错误消息:UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 46: ordinal不在范围内(128)。似乎 Python 尝试转换为 ascii,它会找到无法转换的字符。我的文本包含非 ASCII 字符。
    【解决方案3】:

    错误发生在这一行

    usock.send("TEXT %s\nENDQ\n" % text.replace("\n", " ").encode("utf-8"))
    

    我可以通过这种方式重现类似的错误:

    In [23]: text = 'äö'
    
    In [24]: 'TEXT %s'%text.replace("n", " ").encode('utf-8')
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
    

    虽然您已经证明 f_strunicode,但不知何故,text 是一个 str 对象。您在f_strtext 之间进行的一些额外处理可能使text 成为str

    如果您可以将所有输入转换为 unicode,将它们作为 unicode 使用,并且仅在输出时转换回特定编码(根据需要),您的问题应该得到解决。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-23
      • 1970-01-01
      • 2014-05-21
      相关资源
      最近更新 更多