Найти - Пользователи
Полная версия: [csv + utf8] Модуль csv. Что это за косяк с первыми данными из файла?
Начало » Python для новичков » [csv + utf8] Модуль csv. Что это за косяк с первыми данными из файла?
1
Pluto
Есть csv-файл. Он в кодировке utf-8
 csv_file = open(path, encoding = 'utf-8')
csv_reader = csv.reader(csv_file)

Допустим в файле такие две строки:
FIRST_DATA, SECOND_DATA
THIRD_DATA, FOURTH_DATA

 for row_from_csv in csv_reader:
    print (row_from_csv)
В итоге получаем:
 ['\ufeffFIRST_DATA', 'SECOND_DATA'']
['THIRD_DATA', 'FOURTH_DATA']

Что это за ‘\ufeff’?

Почему это значение прицепляется к первому значению из первой строки csv-файла?
Причём, если в первом print попытаться вывести не весь список,
а только первый элемент
 print (row_from_csv[0])
, то получим в консоли
FIRST_DATA
якобы без мусора в начале.

Долго же я мучился, пытаясь сверить первый элемент первого списка со значением “FIRST_DATA”, а получалось, что
 print (row_from_csv[0], " == FIRST_DATA", row_from_csv[0] == 'FIRST_DATA')
выдавало в консоли “чудесный” результат:
FIRST_DATA == FIRST_DATA False

Это какой-то косяк csv.reader? Может, я чего-то не знаю и что-то упускаю? Как избавиться от этого \ufeff?
Romissevd
Первая ссылка google
py.user.next
Pluto
Что это за ‘\ufeff’?
Это BOM (byte order mark) - признак, который сообщает об эндианстве. Эти два байта сами по себе упорядочены - 0xfe меньше, чем 0xff. Поэтому в зависимости от хранения, они идут либо в таком порядке, либо в обратном. Причём это нужно только для utf-16 и utf-32, так как они хранятся в виде многобайтовых целых чисел (у которых и есть эндианство), но его добавляют и к utf-8, хоть utf-8 и находится всегда в большом эндианстве, так как она состоит из однобайтовых целых чисел (у которых нет эндианства). По-моему, его стали добавлять к utf-8 из-за редакторов, которые его всегда искали. То есть он никак не помогает раскодировать utf-8.
Pluto
Спасибо за помощь. Что-то не додумался искать в яндексогуглах именно по \ufeff. Устал, видать, вчера.
Буду выбрасывать сие значение из первого элемента путём row_from_csv.replace(“\ufeff”, “”)

Зачем же csv.reader выдаёт это значение в качестве части первого элемента из csv-файла?
csv.reader ничего не знает про этот BOM?
Как-то это неудобно постоянно помнить про этот бом-би-бом и не забывать при считывании данных отбрасывать его в первом элементе.
py.user.next
Pluto
csv.reader ничего не знает про этот BOM?
Да, для него это просто часть строки. Формат csv тем и хорош, что не отбрасывает ничего, он сделан для точной передачи данных, какие бы они ни были.
doza_and
Pluto
Как-то это неудобно постоянно помнить про этот бом-би-бом и не забывать при считывании данных отбрасывать его в первом элементе.
Посмотрите как все развивалось. Вначале было достаточно 7 бит на одну букву. Потом начали использовать восьмой, в каждой стране по своему. Поэтому чтобы понять как отображать символы нужна дополнительная информация. В windows-rus например одновременно используются 2 способа cp866 и cp1251. Люди начали придумывать как добиться однозначности трактовки содержимого файлов. Договорились что будут использовать unicode. Но к сожалению придумали несколько способов упаковки его в файлы utf-5 utf-6 utf-8 utf-16LE/BE UTF-32LE/BE… Чтобы различить эти некоторые из этих способов придумали BOM. На мой взгляд сейчас идет активный процесс вымывания старых кодировок (cp1251 cp866 и т.п.). Среди используемых кодировок похоже побеждает utf-8. Например в новых наших проектах декларируется использование только utf-8. Тогда BOM не нужен.

Мораль. Не следует ждать что в csv добавят обработку BOM. Народ просто будет ждать когда он сам вымрет. Не надо мучаться с BOM, чтото там выкидывать проверять номер строки и т.п., настройте средство которым вы получаете файл так чтобы оно не добавляло bom. Если не получится сделайте фильтр который будет выкидывать bom и приводить все фходные файлы в utf-8 без bom.
PooH
 with open(path, encoding='utf_8_sig') as csv_file:
    csv_reader = csv.reader(csv_file)
    for row_from_csv in csv_reader:
        print(row_from_csv)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB