Почему конкатенация строк Python работает с русским текстом, а string.format() - нет
Я пытаюсь проанализировать (и избежать) строки файла CSV, который хранится в кодировке символов Windows-1251. Используя этот превосходный ответ, чтобы справиться с этой кодировкой, я закончил этой строкой для проверки вывода, по некоторым причинам это работает:
print(row[0]+','+row[1])
Выведение:
Тяжелый Уборщик Обязанности,1 литр
Пока эта строка не работает:
print("{0},{1}".format(*row))
Вывод этой ошибки:
Name,Variant
Traceback (most recent call last):
File "Russian.py", line 26, in <module>
print("{0},{1}".format(*row))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-3: ordinal not in range(128)
Вот первые 2 строки CSV:
Name,Variant
Тяжелый Уборщик Обязанности,1 литр
и в случае, если это поможет, вот полный источник Russian.py:
import csv
import cgi
from chardet.universaldetector import UniversalDetector
chardet_detector = UniversalDetector()
def charset_detect(f, chunk_size=4096):
global chardet_detector
chardet_detector.reset()
while 1:
chunk = f.read(chunk_size)
if not chunk: break
chardet_detector.feed(chunk)
if chardet_detector.done: break
chardet_detector.close()
return chardet_detector.result
with open('Russian.csv') as csv_file:
cd_result = charset_detect(csv_file)
encoding = cd_result['encoding']
csv_file.seek(0)
csv_reader = csv.reader(csv_file)
for bytes_row in csv_reader:
row = [x.decode(encoding) for x in bytes_row]
if len(row) >= 6:
#print(row[0]+','+row[1])
print("{0},{1}".format(*row))
3 ответа
Строки в вашем списке, вероятно, уже были в Unicode, поэтому у вас не возникло проблем.
print(row[0]+','+row[1])
Тяжелый Уборщик Обязанности,1 литр
Но здесь мы пытаемся добавить юникод к нормальной строке! Вот почему вы получаете UnicodeEncodeError
,
print("{0},{1}".format(*row))
Так что просто измените его на:
print(u"{0}, {1}".format(*row))
Ты используешь str.format()
который преобразует unicode()
в str()
неявно. Это необходимо сделать для того, чтобы можно было интерполировать значения в предоставленный шаблон.
использование unicode.format()
вместо:
print(u"{0},{1}".format(*row))
Обратите внимание u
перед форматным литералом. unicode.format()
должен декодировать str
входы, чтобы вписаться в результирующий вывод Unicode.
Конкатенация, с другой стороны, может неявно декодировать для получения окончательного unicode()
результат объекта. Если бы ваш ','
значение содержит не-ASCII байты, что неявное декодирование также завершится ошибкой.
Мораль истории: используйте строковые литералы Unicode во всем коде при обработке текста.
+
операнд прекрасно работает между unicode
строка и str
строка. С другой стороны, str.format
не принимает unicode
строки в качестве параметров.
Таким образом, вы можете просто заменить проблемную строку на следующую:
print(u"{0},{1}".format(*row))
Это должно делать свое дело.