Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 24, 2017 18:39:43

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  1  -
Профиль   Отправить e-mail  

[csv + utf8] Модуль csv. Что это за косяк с первыми данными из файла?

Есть 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?

Отредактировано Pluto (Фев. 24, 2017 18:42:44)

Офлайн

#2 Фев. 24, 2017 18:57:22

Romissevd
От: Счастье
Зарегистрирован: 2015-03-01
Сообщения: 533
Репутация: +  76  -
Профиль   Отправить e-mail  

[csv + utf8] Модуль csv. Что это за косяк с первыми данными из файла?

Офлайн

#3 Фев. 25, 2017 03:41:23

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9726
Репутация: +  843  -
Профиль   Отправить e-mail  

[csv + utf8] Модуль csv. Что это за косяк с первыми данными из файла?

Pluto
Что это за ‘\ufeff’?
Это BOM (byte order mark) - признак, который сообщает об эндианстве. Эти два байта сами по себе упорядочены - 0xfe меньше, чем 0xff. Поэтому в зависимости от хранения, они идут либо в таком порядке, либо в обратном. Причём это нужно только для utf-16 и utf-32, так как они хранятся в виде многобайтовых целых чисел (у которых и есть эндианство), но его добавляют и к utf-8, хоть utf-8 и находится всегда в большом эндианстве, так как она состоит из однобайтовых целых чисел (у которых нет эндианства). По-моему, его стали добавлять к utf-8 из-за редакторов, которые его всегда искали. То есть он никак не помогает раскодировать utf-8.



Отредактировано py.user.next (Фев. 25, 2017 03:43:59)

Офлайн

#4 Фев. 25, 2017 09:22:28

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  1  -
Профиль   Отправить e-mail  

[csv + utf8] Модуль csv. Что это за косяк с первыми данными из файла?

Спасибо за помощь. Что-то не додумался искать в яндексогуглах именно по \ufeff. Устал, видать, вчера.
Буду выбрасывать сие значение из первого элемента путём row_from_csv.replace(“\ufeff”, “”)

Зачем же csv.reader выдаёт это значение в качестве части первого элемента из csv-файла?
csv.reader ничего не знает про этот BOM?
Как-то это неудобно постоянно помнить про этот бом-би-бом и не забывать при считывании данных отбрасывать его в первом элементе.

Офлайн

#5 Фев. 26, 2017 01:59:29

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9726
Репутация: +  843  -
Профиль   Отправить e-mail  

[csv + utf8] Модуль csv. Что это за косяк с первыми данными из файла?

Pluto
csv.reader ничего не знает про этот BOM?
Да, для него это просто часть строки. Формат csv тем и хорош, что не отбрасывает ничего, он сделан для точной передачи данных, какие бы они ни были.



Офлайн

#6 Фев. 26, 2017 08:53:14

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

[csv + utf8] Модуль csv. Что это за косяк с первыми данными из файла?

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.



Офлайн

#7 Фев. 26, 2017 13:26:54

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

[csv + utf8] Модуль csv. Что это за косяк с первыми данными из файла?

 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)



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version