Читання Python з файлу та збереження в utf-8


81

У мене проблеми з читанням із файлу, обробкою його рядка та збереженням у файл UTF-8.

Ось код:

try:
    filehandle = open(filename,"r")
except:
    print("Could not open file " + filename)
    quit() 

text = filehandle.read()
filehandle.close()

Потім я трохи обробляю текст змінної.

І потім

try:
    writer = open(output,"w")
except:
    print("Could not open file " + output)
    quit() 

#data = text.decode("iso 8859-15")    
#writer.write(data.encode("UTF-8"))
writer.write(text)
writer.close()

Це чудово виводить файл, але це робиться в ISO 8859-15, на думку мого редактора. Оскільки той самий редактор розпізнає вхідний файл (у назві змінної файлу) як UTF-8, я не знаю, чому це сталося. Наскільки моє дослідження показало, що коментовані рядки повинні вирішити проблему. Однак, коли я використовую ці рядки, результуючий файл має нездійсненність, головним чином, слова з тильдою, оскільки текст на іспанській мові. Я був би дуже вдячний за будь-яку допомогу, оскільки я в тупі ....


2
Який це редактор? Яка версія python? Звідси цей код здається цілком дійсним і повинен працювати, як очікувалося ...
filmor

Кейт - редактор. Результатом роботи python --version є Python 2.7.5+
aarelovich

Я протестував ваш код із версіями 2.6.8, 2.7.5+ та 3.3.2+, і все працює нормально. Не могли б ви навести якийсь приклад введення?
zero323

Оскільки текст оброблявся в необроблених байтах, невидимий код обробки, можливо, зіпсував кодування UTF8.
Mark Tolonen

3
Гаразд. Я це вирішив. Це була здебільшого моя вина, так що всім шкода. Ось що сталося. Код, наданий @MarkTolonen, спрацював, якщо при відкритті файлу я замінюю iso-8859-15 замість utf-8. Однак, коли мій редактор оновлював файл із пам'яті, вже завантаживши старе кодування, він показав мені хитрість. Коли я знову відкрив файл, він показав мені це добре. Дякую всім і вибачте за клопоти !!!
aarelovich

Відповіді:


201

Обробляйте текст до та з Unicode на межі вводу-виводу вашої програми за допомогою codecsмодуля:

import codecs
with codecs.open(filename, 'r', encoding='utf8') as f:
    text = f.read()
# process Unicode text
with codecs.open(filename, 'w', encoding='utf8') as f:
    f.write(text)

Edit:io Тепер модуль рекомендується замість кодеків і сумісний з Python 3 в openсинтаксисі, і при використанні Python 3, ви можете просто використовувати , openякщо вам не потрібно Python 2 сумісності.

import io
with io.open(filename, 'r', encoding='utf8') as f:
    text = f.read()
# process Unicode text
with io.open(filename, 'w', encoding='utf8') as f:
    f.write(text)

6
Я зробив саме те, що ти мені сказав.
Така

1
У мене це працює. Проблема полягала в тому, що оригінальний файл був iso-8859-15
aarelovich

10
Для тих , хто підходить до цього, будь ласка , зверніть увагу , що для Python3 open()і io,open()ті ж. Просто використовуйте open(). Перевірте довідку (відкриту), і ви побачите, що вона така ж, як io.open () - навіть у заголовку написано Довідка про вбудовану функцію, відкриту в модулі io.
Шон Механ

1
@arturomp Це також не буде працювати. io.openочікує, що будуть записані рядки Unicode, а не байтові. Він виконує кодування до оголошеного кодування.
Марк Толонен

1
@arturomp Correction, він не працюватиме на Python 3. Python 2 неявно перетворить байтовий рядок назад в Unicode, використовуючи asciiкодек за замовчуванням , тому він буде працювати, доки рядок буде лише ASCII. Ось чому Python 3 змінив його ... це перешкоджає "він іноді спрацює", що є надокучливою помилкою, яку можна відстежити.
Марк Толонен

10

Ви також можете пройти це за допомогою коду нижче:

file=open(completefilepath,'r',encoding='utf8',errors="ignore")
file.read()

4

Ви не можете зробити це, використовуючи open. використовувати кодеки.

коли ви відкриваєте файл у python за допомогою відкритої вбудованої функції, ви завжди будете читати / писати файл у ascii. Щоб написати це в utf-8, спробуйте:

import codecs
file = codecs.open('data.txt','w','utf-8')

2
Спробував це, і я отримав помилку: UnicodeDecodeError: 'utf8' кодек не може декодувати байт 0xe9 у позиції 57: недійсний байт продовження
aarelovich

Ви економите за допомогою кодування utf-8? дивіться, якщо ви читаєте з іншого файлу, який є ascii, спочатку його потрібно декодувати.
Фернандо Фрейтас Алвес

Код такий, яким ви його бачите. Те, що я зробив, замінило рядок write = open (output, 'w') на writer = codecs.open (output, 'w', 'utf-8'), і це
призвело до
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.