【问题标题】:Python 2.7 and Sublime 2 + unicode don't mixPython 2.7 和 Sublime 2 + unicode 不能混用
【发布时间】:2015-10-08 21:24:36
【问题描述】:

首先,我看过这里:Sublime Text 3, Python 3 and UTF-8 don't like each other 并阅读了The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets,但我仍然不知道以下内容:

从在 Sublime 中创建的文件运行 Python(不是编译)并在 XP 机器上通过命令提示符执行

我有几个以重音命名的文本文件(主要是德语、西班牙语和法语)。我想删除重音字符(变音符号、锐音符、坟墓、cidillas 等)并将它们替换为它们的等价非重音外观。

如果重音是脚本中的字符串,我可以去掉它们。但是访问同名的文本文件会导致 strippAcent 函数失败。我完全没有想法,因为我认为这是由于与 Sublime 和 Python 的冲突。

这是我的脚本

# -*- coding: utf-8 -*-

import unicodedata
import os

def stripAccents(s):
  try:
    us = unicode(s,"utf-8")
    nice = unicodedata.normalize("NFD", us).encode("ascii", "ignore")
    print nice
    return nice
  except:
    print ("Fail! : %s" %(s))
    return None   


stripAccents("Découvrez tous les logiciels à télécharger")
# Decouvrez tous les logiciels a telecharger 
stripAccents("Östblocket")
# Ostblocket
stripAccents("Blühende Landschaften")
# Bluhende Landschaften

root = "D:\\temp\\test\\"

for path, subdirs, files in os.walk(root):
  for name in files:
    x = name
    x = stripAccents(x)

记录在案:

C:\chcp

给我 437

这是代码为我生成的:

完整的错误是:

C:\WINDOWS\system32>D:\LearnPython\unicode_accents.py
Decouvrez tous les logiciels a telecharger
Ostblocket
Bluhende Landschaften
Traceback (most recent call last):
  File "D:\LearnPython\unicode_accents.py", line 37, in <module>
    x = stripAccents(x)
  File "D:\LearnPython\unicode_accents.py", line 8, in stripAccents
    us = unicode(s,"utf-8")
UnicodeDecodeError: 'utf8' codec can't decode byte 0xfc in position 2:   invalid start byte

C:\WINDOWS\system32>

【问题讨论】:

  • 您到底想做什么 - 重命名文件?因为你没有在你的脚本中这样做。您只需阅读它们的名称,然后通过您的函数运行名称。您永远不会尝试将该文件名写回磁盘...
  • 请包含运行脚本的完整输出,包括错误消息。
  • @MattDMo 是的,我现在正在调试。它目前没有重命名。在整理字符串之前,我没有包含重命名代码。
  • 不要捕获异常并打印Fail,而是注释掉except 块(以及try:)并查看实际错误是什么。然后你就会知道如何解决它。
  • @MattDMo 按要求添加了错误。

标签: python-2.7 unicode sublimetext2 python-unicode


【解决方案1】:
root = "D:\\temp\\test\\"
for path, subdirs, files in os.walk(root):

如果您想以原生 Unicode 格式读取 Windows 的文件名,您必须通过将 Unicode 字符串传递给文件系统函数来具体要求:

root = u"D:\\temp\\test\\"

否则 Python 将默认使用标准的基于字节的文件系统接口。在 Windows 上,这些文件名以系统特定区域设置的旧式编码(ANSI 代码页)编码返回给您。

在 stripAccents 中,您尝试使用 UTF-8 对从此处获得的字节字符串进行解码,但 ANSI 代码页绝不是 UTF-8,而且您拥有的字节序列也不是有效的 UTF-8 序列所以你得到一个错误。您可以使用伪编码 mbcs 从 ANSI 代码页进行解码,但最好坚持使用 Unicode 文件路径字符串,这样您就可以包含不适合 ANSI 的字符。

【讨论】:

  • 谢谢!现在都在工作。 一个字母会产生很多的不同!
【解决方案2】:

始终使用 Unicode 字符串来表示 Python 中的文本。在顶部添加 from __future__ import unicode_literals 以便所有 "" 文字都将创建 Unicode 字符串。或者在任何地方使用 u"" 文字。从stripAccents() 中删除unicode(s, 'utf-8'),始终传递Unicode 字符串(尝试unidecode 包,将Unicode 音译为ascii)。

使用 Unicode 透明地解决了几个问题:

  • 不会有UnicodeDecodeError,因为Windows 为文件名提供了Unicode API:如果你传递Unicode 输入;你会得到 Unicode 输出
  • 当包含使用 Windows 编码(例如 cp1252)编码的文本的字节字符串使用 cp437 编码(例如 Blühende -> Blⁿhende(ü 已损坏)显示在控制台中时,您将不会得到 mojibake )
  • 您可能能够处理既不能使用 cp1252 也不能使用 cp437 编码表示的文本,例如 '❤' (U+2764 HEAVY BLACK HEART)。

要将 Unicode 文本打印到 Windows 控制台,您可以使用 win-unicode-console 包。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 2014-02-05
    • 1970-01-01
    • 2013-04-13
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多