2015-10-08 6 views
0

Прежде всего, я смотрел здесь: 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 но я до сих пор не мудрее на следующее:Python 2.7 и Sublime 2 + юникода не смешивать

Запуск Python из файла, созданного в Sublime (не компиляция) и выполнение с помощью командной строки на компьютере 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

Это то, что код производит для меня: enter image description here

Ошибка полный:

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> 
+0

Что именно вы пытаетесь сделать - переименовать файлы? Потому что вы не делаете этого в своем скрипте. Вы просто читаете их имена, а затем запускаете имя через свою функцию. Вы никогда не пытаетесь записать это имя файла на диск ... – MattDMo

+0

Пожалуйста, включите полный вывод запуска скрипта, включая сообщения об ошибках. – roeland

+0

@MattDMo Да, сейчас я отлаживаю. В настоящее время он ничего не переименовывает. Я не включил код переименования, пока не отсортировал строки. –

ответ

1
root = "D:\\temp\\test\\" 
for path, subdirs, files in os.walk(root): 

Если вы хотите прочитать имена файлов Windows в их нативной форме Unicode, вы должны спросить, что specfically, передача строки Unicode в файловой системе функции:

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

В противном случае Python будет по умолчанию используя стандартные байт-интерфейсы для файловой системы. В Windows эти имена возвращаются к вам, закодированные в кодировке устаревшего кода, зависящей от локали (кодовая страница ANSI).

В stripAccents вы пытаетесь декодировать строку байта, которую вы получили отсюда, используя UTF-8, но кодовая страница ANSI никогда не является UTF-8, а последовательность байтов, которую вы имеете, не является действительной UTF-8 чтобы вы получили сообщение об ошибке. Вы можете декодировать с кодовой страницы ANSI с помощью псевдокодирования mbcs, но лучше было бы придерживаться строк файла Unicode, чтобы вы могли включать символы, которые не соответствуют ANSI.

+0

Спасибо! Теперь все работает. ** ** ** ** ** ** ** ** ** ** ** ** ** * –

0

Всегда используйте строки Unicode для представления текста в Python. Добавьте from __future__ import unicode_literals вверху, чтобы все литералы "" создавали строки Unicode. Или используйте литералы u"" всюду. Drop unicode(s, 'utf-8') от stripAccents(), всегда передавайте строки Unicode (попробуйте unidecode пакет, чтобы транслитерировать Unicode в ascii).

Использование Unicode решает несколько проблем, прозрачно:

  • не будет UnicodeDecodeError, поскольку для Windows предоставляет API Unicode для имен файлов: если вы передаете Unicode ввода; вы получаете выход Unicode
  • вы не получите mojibake, если в консоли отображается строка, содержащая текст, закодированный с использованием вашей кодировки Windows, такой как cp1252, используя кодировку cp437, например., Blühende ->Blⁿhende (ü поврежден)
  • вы могли бы работать с текстом, который не может быть представлен с использованием ни cp1252, ни cp437 кодирования, например, '❤'(U+2764 HEAVY BLACK HEART).

Чтобы напечатать текст Unicode в консоли Windows, вы можете использовать пакет win-unicode-console.