Я использую Python для чтения текстового файла данных построчно. Одна из строк содержит символ степени. Я хочу изменить эту часть строки. В моем сценарии используется line = line.replace("TEMP [°C]", "TempC"). Мой код останавливается на этой строке, но вообще не меняет жало и не выдает ошибку. Очевидно, в моей замене есть что-то такое, что скрипт не видит «TEMP [°C]» как существующую в моей строке.
Чтобы вставить знак градуса в мой скрипт, мне пришлось изменить кодировку на UTF-8 в настройках файла IDE. Я включил следующий текст в начало своего сценария.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
Как заменить «TEMP [°C]» на «TempC»?
Я использую Windows 7 и Python 2.7 с Komodo IDE 5.2.
Я попытался запустить предложенный код в оболочке Python в Komodo, и это изменило файл.
# -*- coding: utf-8 -*-
line = "hello TEMP [°C]"
line = line.replace("TEMP [°C]", "TempC")
print(line)
hello TempC
Этот предложенный код в оболочке Python в Komodo вернул это.
line = "TEMP [°C]"
line = line.replace(u"TEMP [°C]", "TempC")
Traceback (most recent call last):
File "<console>", line 0, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 6: ordinal not in range(128)
Однако ни одно из этих предложений не сработало при чтении моего текстового файла.
Вы открываете файл с помощью простого open или используете io.open для правильного/автоматического декодирования в unicode? И какая кодировка файла, из которого вы читаете? Если вы используете обычный open, читая из файла, отличного от UTF-8, вы получите другой str, чем тот, который вы получили здесь ("TEMP [°C]" на самом деле 'TEMP [\xc2\xb0C]', но если файл, из которого вы читаете, latin-1 , вы бы прочитали в 'TEMP [\xb0C]' (обратите внимание на отсутствие \xc2, которого требует представление utf-8).
@GBG: редактирование просто предполагает, даже более убедительно, что кодировка файла не является UTF-8. Является ли Windows или UNIX-подобным? Если второе, попробуйте запустить file NAMEOFYOURINPUTFILE в командной строке; Я предполагаю, что это говорит вам что-то вроде NAMEOFYOURINPUTFILE: ISO-8859 text, а не текст utf-8.
@ShadowRanger. Я использовал ссылку ниже, чтобы определить, что файл, который я читаю, использует кодировку ANSI. Я попытался добавить import io и открыть файл с помощью io.open, но строка не изменилась.stackoverflow.com/questions/3710374/…






Вы должны использовать флаг u для строкового литерала Unicode:
line = line.replace(u"TEMP [°C]", "TempC")
@mrk - я пробовал оба подхода, и ни один из них не работал. Я не понимаю, почему они не работают.
Этот код у меня работает нормально (Python 2.7.14). Может быть, вы можете указать, сделали ли вы что-то другое, чтобы мы могли взять это отсюда.
# -*- coding: utf-8 -*-
line = "hello TEMP [°C]"
line = line.replace("TEMP [°C]", "TempC")
print(line)
# hello TempC
Примечание: Мне не нужен был флаг u.
Основываясь на ваших симптомах, ваши str литералы Python становятся их utf-8 кодировками, поэтому, когда вы вводите:
"TEMP [°C]"
вы на самом деле получаете:
'TEMP [\xc2\xb0C]'
Ваш файл имеет другую кодировку (например, latin-1 или cp1252), и, поскольку вы читаете его через обычный open, вы получаете обратно некодированный str. Но в кодировках latin-1 и cp1252str — это 'TEMP [\xb0C]' (обратите внимание на отсутствие \xc2), поэтому сравнение str не считает две строки эквивалентными.
Лучшее решение — заменить использование open на io.open, в котором используется версия open для Python 3, которая может беспрепятственно декодировать с использованием заданной кодировки для создания канонических представлений unicode, и аналогичным образом использовать литералы unicode вместо str в (для Python) кодировка неизвестна, поэтому нет разногласий по поводу правильного представления символа степени (в unicode есть одно и только одно представление):
import io
with io.open('myfile.txt', encoding='cp1252') as f:
for line in f:
line = line.replace(u"TEMP [°C]", u"TempC")
Как вы описываете в своих изменениях, ваш файл, скорее всего, cp1252 (ваш редактор говорит, что это ANSI, это просто глупый способ описать cp1252), поэтому выбран encoding.
Примечание. Если вы собираетесь использовать unicode последовательно во всей своей программе (достойная идея, если вы имеете дело с данными, отличными от ASCII), вы можете сделать это по умолчанию:
from __future__ import unicode_literals
# All string literals are unicode literals unless prefixed with b, as on Python 2
from io import open # open is now Python 3's open
# No need to qualify with `io.` for `open`, nor put `u` in front of Unicode text
with open('myfile.txt', encoding='cp1252') as f:
for line in f:
line = line.replace("TEMP [°C]", "TempC")
На самом деле вам следует просто перейти на Python 3, где вся эта проблема «unicode и str пытаются работать вместе и часто терпят неудачу» была решена путем полного разделения двух типов.
@GBG: Рад, что смог помочь. Если я когда-нибудь заставлю свою машину времени работать, я вернусь в 1980-е и заставлю всех с самого начала переключиться на UTF-8 как на единственную истинную кодировку текста, чтобы мы не застряли, имея дело с Windows и ее локалью. специальные ASCII-надмножества кодировок один байт на символ, которые ничего не делают, но причиняют вам боль в тот момент, когда вам нужна одна не-ASCII-вещь в вашей программе.
Ваш код отлично работает для меня в интерактивном режиме Python 2.7.