【问题标题】:Special character encoding is lost when string is passed to function将字符串传递给函数时会丢失特殊字符编码
【发布时间】:2016-03-23 12:58:48
【问题描述】:
string = "Magic Cookie® Extra"
print string

会给出输出:

"Magic Cookie® Extra"

但是,如果我将字符串传递给这个函数,它将与另一个字符串结合起来:

def label_print(label, string):
    print label + ": " + string

label_print("Product name", string)

会给出输出:

"Product name: Magic Cookie?? Extra"

为什么会这样,我该如何预防?

与第一个字符串的连接是否会重置编码,以便® 字符变为??

我已尝试编辑函数,使局部变量 labellabel.encode("utf-8"),但这无济于事。

我的 Python 文件顶部还有 # -*- coding: utf-8 -*-

【问题讨论】:

  • 那是 Python 2 还是 3?
  • @AaronDigulla Python 2.7。抱歉,将更新标签。
  • 您在哪里运行该代码?它在 Jupyter 笔记本中给了我一个 UnicodeDecodeError(这是我所期望的),我什至无法在 python 控制台中粘贴 ®。
  • 不幸的是,我无法在我的 Linux 和 Windows 系统上真正重现这一点,其中 string.encode("utf-8") 行实际上会生成 UnicodeDecodeError 异常。文本在 Linux 上显示良好,尽管 Windows 在这两种情况下都会产生乱码。
  • 我猜你忘了提到来自__future__的一些导入。

标签: python python-2.7 encoding utf-8


【解决方案1】:

正如您在 cmets 中所说,该字符串是从网页中抓取的,以下是对所发生情况的可能解释。 UTF8 将 127 以上的字符编码为多字节字符。例如® 字符的代码为0xae,在utf8 中编码为'\xc2\xae'

所以你的字符串实际上是'Magic Cookie\xc2\xae Extra',当连接时会导致'Product name: Magic Cookie\xc2\xae Extra'

正如@AaronDigulla 解释的那样,这两个特殊字符随后被翻译为? 给出结果。

获得它的一致方法是将encode 方法与'replace' 错误处理程序一起使用:

>>>> print 'Product name: Magic Cookie\xc2\xae Extra'.decode('ascii', 'replace').encode('ascii', replace')
Product name: Magic Cookie?? Extra

但是,除非你确切地说出你做什么和你想要什么,否则我无法告诉你如何解决......

【讨论】:

  • 谢谢谢尔盖!如果我在您概述的方向上发现某些东西,我将对此进行进一步调查并相应地应用“已回答的问题”。目前,它实际上与我对string.encode("utf-8") 所做的相反,即string.decode("utf-8")。我还不确定为什么会这样。
【解决方案2】:

如果我运行你的代码,我会得到

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 12: ordinal not in range(128)

当我尝试拨打string.encode('UTF-8') 时,这里还有其他事情在起作用。

一般来说,您不能将 UTF-8 编码的字符串与非 UTF-8 编码的字符串混用。要么一切都被编码,要么什么都没有。没有混合。

在 Python 2 中解决这些问题的一种方法是使用 unicode 字符串:

string = u"Magic Cookie® Extra"
print repr(string)
print repr('a ' + string + ' b')

哪个打印:

u'Magic Cookie\xae Extra'
u'a Magic Cookie\xae Extra b'

如您所见,即使串联中的字符串不是 unicode 字符串,Pyhton 也会“升级”它们。这会很好用......除非你在某处有 UTF-8 编码的字节字符串......

注意:? 表示有人为sys.stdout 安装了一个输出转换器,它将未知/不可打印的字符转换为?。在您的所有来源中搜索sys.stdout,找出发生这种情况的原因。

【讨论】:

  • 感谢您的回复 - 抱歉,我无法创建一个最小、完整和可验证的示例。我现在尝试重新创建我认为对于此错误至关重要的代码链,但我无法重现它。我的原始程序(大约 600 行)中有一些东西在这里意外交互,所以我可能不得不重新审视这个问题。
猜你喜欢
  • 2019-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-14
  • 2012-09-07
相关资源
最近更新 更多