Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 12, 2016 16:07:59

netilov
Зарегистрирован: 2016-10-12
Сообщения: 1
Репутация: +  0  -
Профиль   Отправить e-mail  

Запись в файл, символ \u2020

Добрый день. Пытаюсь записать в файл строку, в которой есть символ ‘†’ (\u2020), делаю это так -

 line = 'test †'
with open('filetest.bin', 'wb') as file:
    file.write(line.encode())

Проблема в том, что если я запускаю скрипт из PyScripter, то все прекрасно работает и файл создается, если же запускаю скрипт из командной строки, то выводит ошибку -
UnicodeEncodeError: ‘charmap’ codec can't encode character ‘\u2020’ in position 9: character maps to
<undefined>

Что не так?

Офлайн

#2 Окт. 12, 2016 16:56:49

ZerG
Зарегистрирован: 2012-04-05
Сообщения: 2627
Репутация: +  61  -
Профиль   Отправить e-mail  

Запись в файл, символ \u2020

в начало файла

 # -*- coding: utf-8 -*-


 line.decode('utf-8').encode('utf-8')



Влодение рускай арфаграфией - это как владение кунг-фу: настаящие мастира не преминяют ево бес ниабхадимости

Отредактировано ZerG (Окт. 12, 2016 16:57:14)

Офлайн

#3 Окт. 12, 2016 20:20:03

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

Запись в файл, символ \u2020

netilov
Пытаюсь записать в файл строку, в которой есть символ ‘†’ (\u2020)
Зависит от версии питона то, как это делается. Если второй питон, то надо использовать юникодовую строку с u в начале, а файл открывать через codecs.open() с указанием кодировки. Если третий питон, то надо просто указать кодировку при открытии файла.



Отредактировано py.user.next (Окт. 12, 2016 20:20:18)

Офлайн

#4 Окт. 13, 2016 02:27:30

Iskatel
Зарегистрирован: 2015-07-29
Сообщения: 291
Репутация: +  3  -
Профиль   Отправить e-mail  

Запись в файл, символ \u2020

py.user.next
codecs.open()
В чем такая обязательность? Файл читается байтиками, и пофиг в какой он кодировке. Потом можно ее привести к требуемой. Или не приводить, если файл например нужно скопировать… ИМХО непременность перекодирования в какието строки скрывает возможность обычных байтов хранить инфу даже на инопланетном языке…

А если ближе к теме ТС, то стоит перевести эти два байта в бинарную форму и, “о чудо” без гемора в файле окажутся именно они.

Офлайн

#5 Окт. 13, 2016 05:03:26

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

Запись в файл, символ \u2020

Iskatel
В чем такая обязательность? Файл читается байтиками, и пофиг в какой он кодировке.
Давно уже принято во всех языках использовать юникод в программах. Прямо как возможность такая появилась, так и приняли все такое правило. А до этого всё в байтах читали. Второй питон унаследовал стиль из 90-х годов (время развития юникода), поэтому там всё так и сделано неудобно. А третий питон уже из нулевых, поэтому в нём сделано всё так, как и должно быть - байты используются только тогда, когда это нужно.

Iskatel
ИМХО непременность перекодирования в какието строки скрывает возможность обычных байтов хранить инфу даже на инопланетном языке
Так инопланетянин на своём языке запишет что-нибудь, а ему скажут “а ты сначала перекодируй в байты”. Ему это зачем? Ты же когда в блокноте текст читаешь, не думаешь, что он в такой-то кодировке, тебе буквы нужны конкретные, а не заморочки.



Отредактировано py.user.next (Окт. 13, 2016 05:08:22)

Офлайн

#6 Окт. 14, 2016 00:33:52

Iskatel
Зарегистрирован: 2015-07-29
Сообщения: 291
Репутация: +  3  -
Профиль   Отправить e-mail  

Запись в файл, символ \u2020

И всегда упор на текст…
Нам, выросших на асме и сях, нифига не понятно почему файл === текст
ИМХО для начала им стоит понять что такой файл, и что “текста” в мире проценов 10 от всего “фаиловового имущества”

А если конкретнее, то понимание что такое файл, очень быстро решает вопросы с кодировками и.т.п.

Ведь многие даже не знают, что копм не знает букв… для них это откровение.

Офлайн

#7 Окт. 14, 2016 09:00:04

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

Запись в файл, символ \u2020

Iskatel
не понятно почему файл === текст
Еще надо взять выросших на UNIX. файл это поток байт (для инопланетян можно побить на биты)
py.user.next
тебе буквы нужны конкретные, а не заморочки.
Так что думаю Isketel прав.
Более того, для чего нужны кодировки и unicode? Может ошибаюсь но по сути unicode обеспечивает выполнение одной дополнительной операции - взятие буквы по целочисленному индексу. А теперь загляните к себе в код, определите когда вы в последний раз делали такую операцию (не позиционирование в слове по заранее взятой при помощи аналога tell позиции а именно взятие по вычисленному индексу). Да utf файл нельзя корректно разрезать в произвольных местах, но это никому и не нужно.

В питоне и букв то нет, есть только текст, так что вполне можно использовать не unicode а utf-8. Так что распространение unicode это дань старым технологиям, можно даже назвать вредительством, поскольку увеличивает объем используемой оперативной памяти. Питон просто вынужден поддерживать эту глупость для согласования интерфейсов с внешними приложениями.

А теперь вопрос в чем я не прав? Может я не знаю для чего нужен unicode?



Офлайн

#8 Окт. 14, 2016 12:43:29

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

Запись в файл, символ \u2020

doza_and
Может ошибаюсь но по сути unicode обеспечивает выполнение одной дополнительной операции - взятие буквы по целочисленному индексу.
Вот как это выглядит в третьем питоне
  
>>> '탡' * 10
'탡탡탡탡탡탡탡탡탡탡'
>>>

А вот так это выглядит во втором
  
>>> '탡'
'\xed\x83\xa1'
>>> '탡' * 10
'\xed\x83\xa1\xed\x83\xa1\xed\x83\xa1\xed\x83\xa1\xed\x83\xa1\xed\x83\xa1\xed\x83\xa1\xed\x83\xa1\xed\x83\xa1\xed\x83\xa1'
>>>

И надо заметить, что дело ещё в лине происходит. В винде же ты вообще не сможешь закодировать это в кодировку по умолчанию.
В третьем питоне я легко могу подстроку взять из определённых символов, а во втором ты даже не поймёшь, где они начинаются.

doza_and
А теперь вопрос в чем я не прав? Может я не знаю для чего нужен unicode?
Да, скорее всего.
Разжёвано здесь, в dip3. strings
Как минимум ты можешь хранить всё в том виде, в котором оно и используется человеком, даже ничего никуда не сохраняя. А если же сохраняешь, то легко можешь посчитать количество символов в файле, какие бы они ни были (сколько бы байт не занимали в той кодировке, которой закодированы).



Отредактировано py.user.next (Окт. 14, 2016 12:50:59)

Офлайн

#9 Окт. 14, 2016 20:40:06

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

Запись в файл, символ \u2020

py.user.next
А вот так это выглядит во втором
Ваш пример не имеет отношения к обсуждаемому примеру. Я ведь не против типа string. Вопрос что в нем хранить unicode или utf-8. Очевидно что корректное отображение на консоли или в файлах этих данных будет абсолютно идентично.
py.user.next
В третьем питоне я легко могу подстроку взять из определённых символов
Вот в этом и суть. Как вы будете брать подстроку? Зачем ее брать?

Т.е. для unicode мы получаем упрощение взятия подстроки по заданным индексам и принципиально усложняем операции файлового ввода вывода.
Для utf-8 - ввод вывод тривиален. Поиск по индексу именно буквы операция сложности O(N) где N длина строки.

Я утверждаю что взятие по индексу практически никогда не нужно, поэтому логично было хранить данные в виде utf-8 в памяти питона.

py.user.next
Как минимум ты можешь хранить всё в том виде, в котором оно и используется человеком
Человек зырит в файл или на консоль. И ему пофиг unicode это или utf-8, главное чтобы выглядело корректно.

Да бывают горе программисты которые для того чтобы взять циферку из строки пальцем считают по буквам где у нее начало и где конец потом выкусывают и преобразуют в значение. А потом долго удивляются что их программа при любом чихе ломается.

Ну не могу я придумать практических примеров взятия срезов по индексам букв!!! В жизни не было ни разу такого.

Насколько я знаю историю вопроса, выбор в пользу unicode был сделан на основе аргумента что кодировки с переменным количеством байт на букву слишком сложны для реализации. Однако история показала что сейчас они везде используются без проблем. Т.е. логично выкинуть unicode на помойку вместе со всеми encode decode (за исключением случая перекодирования между cp1251 utf-8 koi и т.п.) Ну и в питоне тоже внутреннее представление строк сделать utf-8.



Отредактировано doza_and (Окт. 14, 2016 20:44:29)

Офлайн

#10 Окт. 14, 2016 21:08:15

Iskatel
Зарегистрирован: 2015-07-29
Сообщения: 291
Репутация: +  3  -
Профиль   Отправить e-mail  

Запись в файл, символ \u2020

Я рискую быть обруганым, но всеже: причем тут нафиг строки??? Неужели файлы состоят только из строк?

Прошерстите свои диски и скажите столько именно текстовых файлов на нем? (для тех кто на винде https://windirstat.net в помощь)

Киношки, фотки и т.п. Питон не может чтоль? А какже opencv например?

Или взять вот rtmp всеми любимый поток для флеша, на AC3… Вы его как разбирать будете? а в нем и видео и служебные команды, и да, вами любимые строки…

Студента учат строкам, студент расстроен, что питон кроме строк ничего не умеет, питон помирает… Гдето так

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version