【问题标题】:python :same character, different behaviorpython:相同的字符,不同的行为
【发布时间】:2015-06-25 18:09:24
【问题描述】:

我正在从使用 Python 2.7.9 的 postgres 数据库中提取的列表中生成文件名。在这个列表中有带有特殊字符的单词。通常我使用''.join() 记录名称并将其发送到我的装载机,但我只有一个想要被识别的名称。 .py 设置为 utf-8 编码,但单词是葡萄牙语,我认为是 latin-1 编码。

from pydub import AudioSegment
from pydub.playback import play
templist = ['+ Orégano','- Búfala','+ Rúcola']
count_ins = (len(templist)-1)
while (count_ins >= 0 ):
    kot_istructions = AudioSegment.from_ogg('/home/effe/voice_orders/Voz/'+"".join(templist[count_ins])+'.ogg')
    count_ins-=1
    play(kot_istructions)

前两个文件被加载:

/home/effe/voice_orders/Voz/+ Orégano.ogg

/home/effe/voice_orders/Voz/- Búfala.ogg

第三个应该是:

/home/effe/voice_orders/Voz/+ Rúcola.ogg

但是python正在尝试加载

/home/effe/voice_orders/Voz/+ R\xc3\xbacola.ogg

为什么只有这个?我尝试使用normalize() 删除重音,但由于这是一个字符串,因此该方法不起作用。 打印效果很好,因为数据库更新。只是文件名创建不能按预期工作。 建议?

【问题讨论】:

  • Unicode 字符串在 Python 2 中需要“u”前缀:[u'+ Orégano', u'- Búfala', u'+ Rúcola']
  • 请务必使用迭代而不是手动计算索引。一个简单的for word in templist 就足够了。然后,摆脱 join-call,它只是偶然在这里工作,因为你只有一个参数是一个字符串 - 它并没有真正按照你的想法做。字符串表示看起来像正确的 utf-8 编码,问题是:您的文件系统的编码是 utf-8 吗?
  • 你考虑过使用 python 3 吗? Unicode 处理已重做。
  • @dlask :我无法编辑列表,因为它是实时生成的,并用于程序的各个部分。 @deets:有时我需要“即时”编辑索引计数,比for/in 循环编辑更快。我的文件系统(作为我的数据库)设置为 LANG=pt_BR.UTF-8 。 @A.L.Flanagan:我不能。我在 Odoo 中使用 python,我需要 Python 2.7。
  • 不要在问题中加入答案(“已解决”之后的句子)。 Post it as your own answer instead

标签: python string unicode decode encode


【解决方案1】:

看起来根本原因可能是这些名称的编码在您的数据库中不一致。

如果你运行:

>>> 'R\xc3\xbacola'.decode('utf-8')

你得到

u'R\xfacola'

这实际上是一个 Python unicode,正确地表示了名称。那你该怎么办?虽然这是一种非常不干净的编程风格,但您可以玩.encode()/.decode() whackamole,您可以在其中try 使用utf-8 解码来自您的数据库的原始字符串,如果失败,latin-1。它看起来像这样:

try:
    clean_unicode = dirty_string.decode('utf-8')
except UnicodeDecodeError:
    clean_unicode = dirty_string.decode('latin-1')

作为一般规则,始终在您自己的源代码中使用干净的 unicode 对象,并且仅在保存时转换为编码。另外,不要让人们在没有指定编码的情况下将数据插入数据库,因为这会从一开始就阻止你遇到这个问题。

希望有帮助!

【讨论】:

  • 使用.encode()/.decode() 我得到相同的错误,但使用不同的编码:IOError: [Errno 2] No such file or directory: u'/home/effe/voice_orders/Voz/+ R\xfacola.ogg' 意味着您的转换确实有效,但不是我需要的结果。同样,为什么在这个位置只使用ú 而不是在其他情况下?
  • 如果您正在寻找一个已经存在的文件,它的名称中的实际编码是什么?你能浏览到它,看看它的名字是什么吗?尝试运行 os.listdir('/home/effe/voice_orders/Voz/') 并查看它在您的系统中是如何表示的。
  • os.listdir 没有报告任何不妥之处。无论如何这是文件有问题。删除文件并创建一个新文件可以解决问题。请不要问我为什么。感谢您指出这一点,在您的回复中 +1,因为即使不是这种情况,您的方法也让我了解了编码/解码的工作原理。
【解决方案2】:

已解决:文件有问题。删除并重新构建它就可以了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-03
    • 1970-01-01
    • 2015-01-31
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    相关资源
    最近更新 更多