Comments 124
Мне кажется, автор таки перегибает палку местами. Unicode в именах файлов должен быть. Кодировка по умолчанию и в самом деле должна определяться из системной локали — а почему, собственно, должно быть по-другому, ведь зачем она тогда? Многие другие языковые рантаймы так делают уже давно, и вроде бы всех это устраивает.
+3
P.S. Вышесказанное не значит, что я против Python 2, Python 3 или чего-либо ещё.
0
кодировка работы с конослью — да, берите из LANG и LC_*
Но если я открыл файл на чтение — почему ЭТО должно зависеть от локали?
Я блин свой конфиг не смогу прочитать если зайдёт пользователь с другой локалью!
Но если я открыл файл на чтение — почему ЭТО должно зависеть от локали?
Я блин свой конфиг не смогу прочитать если зайдёт пользователь с другой локалью!
+1
./somescript <text.txt — какая должна быть кодировка? С одной стороны это обычный файл, с другой консоль.
0
Ну так скажите, что вам нужно строго UTF-8, если это так важно. Проблемы-то какие?
0
Конфиг не Ваш, а пользовательский. Пользователь решил, в какой кодировке его хранить, а Вам сказал это через
LC_*
.0
А если сисадмин и пользователь пользуются разной локалью?
+2
Хм… Установка программы глобально (в /usr/… например, глобальные конфиги в /etc/… соответственно), один пользователь с ja_JP.EUC-JP, другой с ru_RU.KOI8-R. Что-то мне подсказывает, что проблемы будут у обоих при чтении конфига.
+2
Статус отношений — всё сложно!)
0
С одной стороны, да, должна определяться из локали. Хотя бы для корректного вывода в консоль (Windows уже перешла на Unicode в консоли?). С другой — записывая файл на внешний носитель я, наверное, хочу чтобы он прочитался на другой машине, на которой локаль может быть совсем другая и уж точно не хочу потери информации при записи. Стандартом де-факто для такой записи является одна из кодировок Unicode (UTF-8 в подавляющем большинстве случаев). Универсального решения в голову не приходит, разве что сделать по умолчанию UTF-8, а для stdin/stdout/stderr писать в кодировке локали. Но костыль явный.
0
Нет же. Дать вменяемый API. Нужно Вам ISO-8859-1 — сказали
[fconfigure $f -encoding iso-8859-1]
. Нужно UTF-8 — [fconfigure $f -encoding UTF-8]
. Нужно, чтобы пользователь сам определил — ничего не указывайте. Нужно байтами пожонглировать — [fconfigure $f -encoding binary]
0
Что вменяемый API нужен это понятно. Вопрос в умолчании. Почему пользователь, а не общее для всех скриптов умолчание? А хочешь учесть пользовательские хотелки —
[fconfigure $f -encoding locale]
.+1
Так умолчание пользователь задаёт. Локалью. Она ж для того и предусмотрена.
0
Некоторые пользователи слов таких не знают… И даже на одной машине к общим файлам могут обращаться пользователи с разной локалью.
+1
Если не знают — ну будут использовать локаль по умолчанию, тем более.
0
Не знаю, по мне так лучше бы было чтобы кодировка по умолчанию была одна во всех возможных средах. Решил пользователь сменить локаль (или за него решили) и у него файлы перестали читаться.
0
Я ж говорю: если какие-то конкретные файлы нужно читать с другой кодировкой, программа явно её запросит (а её об этом, в свою очередь, попросит юзер, если захочет). А пока не запросит — дефолтом должна быть та кодировка, которой пользуется пользователь, а не какая-то там UTF-8.
Ну вот стоит у меня, к примеру, какая-нибудь EBCDIC по умолчанию. А программа XYZ требует (!) конфиг в UTF-8. Какого-такого? Мне ради этой программы в редакторе переключать кодировку? Да ни разу, она должна сразу брать конфиг в моём любимом EBCDIC.
Ну вот стоит у меня, к примеру, какая-нибудь EBCDIC по умолчанию. А программа XYZ требует (!) конфиг в UTF-8. Какого-такого? Мне ради этой программы в редакторе переключать кодировку? Да ни разу, она должна сразу брать конфиг в моём любимом EBCDIC.
0
Не согласен.
-2
Поясните.
0
Просто мнение, что файлы на диске, при передаче по сети и т. п., должны храниться в единой кодировке. Грубо говоря, скопировали вы свой конфиг в EBCDIC на флэшку и пришли ко мне поработать, а у меня UTF-8. Что будете делать?
Мнение сформировалось давно, самое позднее в эпоху перехода от CP866 к Windows-1251.
Мнение сформировалось давно, самое позднее в эпоху перехода от CP866 к Windows-1251.
0
Нет единой кодировки. Просто не существует. Unicode не покрывает множество всех возможных символов. Не говоря уже о том, что собственно юникодных кодировок выше крыши.
+1
А что буду делать — у Вас перекодирую. Или Вы перекодируете. В зависимости от того, где и кому нужно. Но у себя я буду хранить в EBCDIC, причём буду ожидать от программ, чтобы они работали сразу в ней без дополнительных телодвижений. На то настройки локали и нужны, чтобы указывать, в какой кодировке работать. (Вообще странно, мне казалось, что это должно быть очевидно, но, видимо, не всегда и не всем.)
0
Как-то вы не о том рассуждаете, не логично получается. Как бы надо отличать для чего предназначен файл. Вы же ко мне не придете с конфигом microsoft word, так? Вы придете со своим юзерским файлом file.txt. То же самое должно быть и у программы на python.
Те данные, которые определяют настройки программы должны быть записаны в определенный файл в кодировке, например, utf-8 и не должны содержать юзерских данных в его кодировке (раз этот файл настроек един для всех юзеров системы).
А вот юзер делает себе какой-либо файл с помощью этой проги и прога сохраняет в кодировке его локали, например, в Вашей EBCDIC. Когда этот файл попадет другому юзеру, тот должен будет позаботиться о его перекодировке (как и всякий из нас получивший странный txt), прежде чем дать его проге. Либо прога может помочь ему с перекодировкой, попытавшись ее определить.
Коротко: конфиг общий — UTF-8, конфиг юзера — его кодировка (EBCDIC).
Те данные, которые определяют настройки программы должны быть записаны в определенный файл в кодировке, например, utf-8 и не должны содержать юзерских данных в его кодировке (раз этот файл настроек един для всех юзеров системы).
А вот юзер делает себе какой-либо файл с помощью этой проги и прога сохраняет в кодировке его локали, например, в Вашей EBCDIC. Когда этот файл попадет другому юзеру, тот должен будет позаботиться о его перекодировке (как и всякий из нас получивший странный txt), прежде чем дать его проге. Либо прога может помочь ему с перекодировкой, попытавшись ее определить.
Коротко: конфиг общий — UTF-8, конфиг юзера — его кодировка (EBCDIC).
0
Господи, 21й век, а все еще обсуждают эти кодировки. Всё кроме юникода должно отправиться к праотцам, туда же, куда отправились четырехкилобайтные машины, неужели это неочевидно?
+1
Расскажите это китайцам и японцам, а потом мы все вместе посмеёмся.
0
А что там не так? Погуглил, не нагуглил.
В юникоде нет части китайского-японского, и не осталось свободных мест?
Ну значит и он должен отправиться к праотцам.
Времена четырехкилобайтных машин прошли. На текст можно тратить сколько угодно места.
В юникоде нет части китайского-японского, и не осталось свободных мест?
Ну значит и он должен отправиться к праотцам.
Времена четырехкилобайтных машин прошли. На текст можно тратить сколько угодно места.
+1
Во-первых, не прошли, а во-вторых, узнайте у тех и других, насколько их устраивает Юникод. Будете удивлены.
0
Да, и не забывайте про:
+1
А ASCII? вообще-то, очень часто используемая кодировка, и я часто к ней прибегал, когда тот же текст, например, с конфигом, где строковые данные не хранятся, если кодирован в UTF-8, то займет больше места, чем в ASCII. А информация в свою очередь не меняется!
0
Ну вот опять. Куда же вы так торопитесь?
Wikipedia: UTF-8 was designed for backward compatibility with ASCII: the first 128 characters of Unicode, which correspond one-to-one with ASCII, are encoded using a single byte with the same binary value as ASCII, so that valid ASCII text is valid UTF-8-encoded Unicode as well.
0
Хорошая статья, спасибо за перевод.
0
Вообще сложно себе представить как это всё происходит. Мелкие скрипты написать так, что бы работали и под python2 и под python3 не проблема, но вот портировать библиотеки… Наверное это действительно огромная головная боль. Плюс ничего не сказано про C-extensions — они остались вполне совместимы между Py2 and Py3?
0
C-extension'ам ещё больше досталось, т.к. очень много изменений в API. Причём есть такие мелкие моменты, что и не обратишь внимание:
Было:
Стало:
Было:
static PyTypeObject mytype = {
PyObject_HEAD_INIT(NULL)
0,
...
};
Стало:
static PyTypeObject mytype = {
PyVarObject_HEAD_INIT(NULL, 0)
...
};
0
Я конечно считаю, что обратную совместимость часто можно выкинуть, но блин они либо не должны затрагивать разработчиков тысяч библиотек, либо должны приносить какую-то реальную и большую пользу.
Вот что полезного дало изменения которое вы показали? Наверное стало что-то «очевиднее», но совсем чуть-чуть.
Вот что полезного дало изменения которое вы показали? Наверное стало что-то «очевиднее», но совсем чуть-чуть.
0
они = «изменения ломающие обратную совместимость»
0
Кстати, вот интересная вещь. Есть такой язык, Tcl. Так вот, несмотря на то, что он постоянно развивается, API меняются таким образом, что минимально ломают обратную совместимость, а чаще всего не ломают совсем. Причём, как на уровне Tcl, так и на уровне C. С большой вероятностью C-расширение, написанное для бородатой версии Tcl, можно с полпинка завести на свежем срезе development-версии. Если же речь идёт о коде на Tcl, то 90% кода работать будет просто сразу, без модификаций, только быстрее :)
0
Ну я вообще работал только с cython и то просто побаловаться и сравнить. Пилил какую-то pygame штуку и привязывал к ней cython математику, собирался сравнить производительность — но так руки и не добрались.
offtop:
как там, кстати с играми на питоне? PyGlet вижу давно не обновлялся. Pygame вроде не плох, но все готовые либы для ускорения ччерез opengl как правило ломают стандартные спрайты и вводят свои. И когда я последний раз проверял такие либы, то все они были или бородатые или бесполезные.
Хочу rapid game development with python с opengl, коллизиями и физикой из коробки! Плюс много сторонних хороших либ для side-scrolling, изометрии, скролинга больших миров и т.д. Из последнего — почти всё есть в pygame, но порой трудно найти.
offtop:
как там, кстати с играми на питоне? PyGlet вижу давно не обновлялся. Pygame вроде не плох, но все готовые либы для ускорения ччерез opengl как правило ломают стандартные спрайты и вводят свои. И когда я последний раз проверял такие либы, то все они были или бородатые или бесполезные.
Хочу rapid game development with python с opengl, коллизиями и физикой из коробки! Плюс много сторонних хороших либ для side-scrolling, изометрии, скролинга больших миров и т.д. Из последнего — почти всё есть в pygame, но порой трудно найти.
0
Ну в Python 3 как раз и шли к максимальной очевидности.
Мне кажется, лучше переболеть один раз, зато избавиться от всех legacy проблем.
Мне кажется, лучше переболеть один раз, зато избавиться от всех legacy проблем.
+1
Обратную совместимость питона итак сломали, поэтому кромсали апи на всю катушку — такая возможность еще не скоро представится :)
0
Десять лет моя жизнь проходит вместе с Python. И пока это бОльшая часть моей жизни.
Правильно ли я понимаю, что Армину 19 лет и python он использует с девяти?
+5
Лично я не буду сильно переживать, если доля питона уменьшится. Уж слишком тормозные вещи на нем выходят.
PS Ну и замены Scheme на Python, в базовых курсах MIT, никогда не прощу.
PS Ну и замены Scheme на Python, в базовых курсах MIT, никогда не прощу.
-19
Минусующие комрады, вы хоть скажите с чем не согласны? Или у меня одного запуск synaptic занимает неприлично много времени?
-6
incogn1too, я лично не минусовал, но фраза «уж слишком тормозные вещи на нём выходят» без приведения конкретных примеров (да и сама по себе) — показывает твою некомпетентность в данной области.
+7
Могу предположить за пренебрежительное отношение к любимому языку минусующих :) А так, по сути, а кто ему на замену придёт? Ruby? JavaScript? прости господи, PHP?
0
Комрады, тормозные вещи на питоне, Scheme. Я думаю ты и двух заданий из SICP не сделал.
+1
Не нравится — напишите свой synaptic на С.
Я считаю, Python вообще не для десктопных аппликаций. В вебе на нем писать легко и приятно, что доказывает огромное кол-во популярных фреймворков (начиная от Tornado, кончая Django и Flask). Замен для себя не вижу — Ruby медленнее (+ учить новый синтаксис, стандарты и тд. — не хочу), JS — пока несерьезно (нет даже неймспейсов — говорить не о чем), Java — на всяких JSF и Spring кол-во кода не идет ни в какое сравнение с тем-же Flask, C# — хоть и по работе занимаюсь с ASP.NET, для своих проектов windows-хостинг заводить не собираюсь (и выкладывать килобаксы за всякие TFS), ASP.NET MVC на Mono выглядит сыро.
Я считаю, Python вообще не для десктопных аппликаций. В вебе на нем писать легко и приятно, что доказывает огромное кол-во популярных фреймворков (начиная от Tornado, кончая Django и Flask). Замен для себя не вижу — Ruby медленнее (+ учить новый синтаксис, стандарты и тд. — не хочу), JS — пока несерьезно (нет даже неймспейсов — говорить не о чем), Java — на всяких JSF и Spring кол-во кода не идет ни в какое сравнение с тем-же Flask, C# — хоть и по работе занимаюсь с ASP.NET, для своих проектов windows-хостинг заводить не собираюсь (и выкладывать килобаксы за всякие TFS), ASP.NET MVC на Mono выглядит сыро.
+1
у блоков Ruby восхитительный дизайн, но по многим причинам он не прижился бы в Python (в его текущем состоянии).
Вот про это было бы интересно почитать…
+5
По файлам не согласен.
А так подо всем подпишусь.
Некоторые вопросы в Python 3 сделаны правильно, но они сделаны правильно в ущерб простоте. А конек Питона в простоте.
Наверное самая большая проблема Python 3 в том, что он ничего не принес нового, кроме проблем и головной боли. Требовалось избавиться от GIL. Чтобы получить быстроту с работающим кодом Python 2 с некоторыми возможными изменениями.
А изменения ради самих изменений ни к чему хорошему не приводят.
Раньше во времена одноядерников Python развивался, сейчас он стоит. Потому что не сделал шаг в сторону девелоперов, не решили проблемы с GIL и простым общением тредов/процессов.
А так подо всем подпишусь.
Некоторые вопросы в Python 3 сделаны правильно, но они сделаны правильно в ущерб простоте. А конек Питона в простоте.
Наверное самая большая проблема Python 3 в том, что он ничего не принес нового, кроме проблем и головной боли. Требовалось избавиться от GIL. Чтобы получить быстроту с работающим кодом Python 2 с некоторыми возможными изменениями.
А изменения ради самих изменений ни к чему хорошему не приводят.
Раньше во времена одноядерников Python развивался, сейчас он стоит. Потому что не сделал шаг в сторону девелоперов, не решили проблемы с GIL и простым общением тредов/процессов.
-1
Всё-таки GIL это часть CPython. Гвидо не раз указывал, что GIL остаётся в его реализации, чтобы не усложнять код. Есть же PyPy, или расширения вроде gevent.
+1
Да, но ни PyPy, ни gevent не решают проблему GIL. Одновременное исполнение нескольких потоков с вычислительными операциями. Единственная попытка решить в лоб — это multiprocessing. А так есть способ писать эффективный код путем смены логики, но не редко за логикой идет и порядочное усложнение кода. Так что «не усложнять» не получается. Раз уж питон все равно обратно не совместим со второй веткой? можно было придумать что-то более эффективное пусть и сложнее. Например в Gо очень хитро придумали с машинами и многопоточностью.
+1
Go всё-таки компилируемый язык со статической типиазацией изначально ориентированный на параллельные вычисления. Мне кажется, что ошибочно сравнивать эти языки.
0
Костыли, опять же.
То есть решения на уровне C нет.
То есть решения на уровне C нет.
0
Я свой веб-фрэймворк и шаблонизотор ене написал (пока), но о строках и кодировках успел составить противоположное мнение. С третьим Питоном функция, принимающая строку, ругается на байты и наоборт. Во втором же неявные
decode('ascii')/encode('ascii')
меня всегда запутывали. Кому вообще нужна кодировка ascii? Приходилось постоянно подглядывать в документацию, чтоб вспомнить, что же именно возвращает очередной метод — чистую строку или в какой-то кодировке. В простых случаях приходилось использовать костыль sys.setdefaultencoding('UTF-8')
.-2
Вы не поверите, но ASCII таки нужна…
+2
Верю. Какой-нибудь URL прочитать, например. Это было маленькое эмоциональное преувеличение.
0
Какой-нибудь URL прочитать, например
Например какой? президент.рф/? Или ta.wikipedia.org/wiki/முதற்_பக்கம்?
0
Вы не поверите, но ASCII таки нужна…
Зачем? Чтобы экономить на размере русских текстов?
0
Как связаны ASCII и русские тексты? КОИ-7?
0
Ну, если подходить с этой стороны, «де-юро», то КОИ-7 к ASCII как раз не относится, зато относятся CP-866 и ISO-8859-5. Русский я взял как более близкий местной аудитории и тот факт, что русские ASCII кодировки практически полностью уступили однобайтовой же ANSI — это лишь такой исторический курьёз. Вместо русского можно взять, к примеру, чешский, где едва ли ни основной (на ряду с ANSI CP-1250) однобайтовой кодировкой всё-ещё является ASCII ISO-8859-2 (если мне не изменяет память, именно она на чешских системах ставится кодировкой по умолчанию в почтовиках типа Outlook, Outlook Express, Windows Mail и Thunderbird).
Если Вы имеете ввиду нижнюю половину, чисто английские тексты, то я вообще не понимаю о чём тут дискутировать, ведь эти символы, на сколько я понимаю, кодируются в UTF-8 идентично ASCII и разницы тут между ними вроде бы нет.
Я говорил о том, что единственный (кроме относительной сложности реализации) известный мне аргумент против UTF-8 (в пользу однобайтовых ASCII/ANSI/KOI) — что текст на языке с интенсивным использованием специфических символов (в частности язык с не-латинской графикой) в однобайтовой кодировке занимает меньше места, чем в UTF-8. Кроме желания сэкономить на этом, не вижу причин использовать кодировки отличные от UTF-8 (можно, конечно, ещё вспомнить об UTF-16 и UTF-32 но, на сколько я понимаю (поправьте если ошибаюсь), по сравнению с UTF-8 они просто устарели).
Понимаю, что рискую прослыть максималистом и вызывать справедливое негодование многих, но считаю, что в современном языке программирования стандартным представлением любой строки (и без всяких костылей) должно быть UTF-8 (на крайняк UTF/UCS-чего-нибудь-ещё). При чтении текста из внешнего потока входная кодировка должна либо (в случае умолчания) браться из локали (на сколько я понимаю, тут так и сделано, что и вызвало негодование автора), либо не браться и считаться априори (спорно) UTF-8, либо указываться программистом явно (надеюсь такая возможность есть, иначе действительно фигня).
В 21-м веке хочется верить, что одно и то же слово будет отображено одинаково (если не говорить о шрифтах) на любой современной машине в любой стране; программируя логику хочется оперировать (не задумываясь применяя строковые операции) именно конкретными буквами (любого языка в любой комбинации), а не байтами.
Если я не прав — буду признателен на указания в чём и почему (кроме соображений экономии — о них, как я уже указал, мне известно).
Если Вы имеете ввиду нижнюю половину, чисто английские тексты, то я вообще не понимаю о чём тут дискутировать, ведь эти символы, на сколько я понимаю, кодируются в UTF-8 идентично ASCII и разницы тут между ними вроде бы нет.
Я говорил о том, что единственный (кроме относительной сложности реализации) известный мне аргумент против UTF-8 (в пользу однобайтовых ASCII/ANSI/KOI) — что текст на языке с интенсивным использованием специфических символов (в частности язык с не-латинской графикой) в однобайтовой кодировке занимает меньше места, чем в UTF-8. Кроме желания сэкономить на этом, не вижу причин использовать кодировки отличные от UTF-8 (можно, конечно, ещё вспомнить об UTF-16 и UTF-32 но, на сколько я понимаю (поправьте если ошибаюсь), по сравнению с UTF-8 они просто устарели).
Понимаю, что рискую прослыть максималистом и вызывать справедливое негодование многих, но считаю, что в современном языке программирования стандартным представлением любой строки (и без всяких костылей) должно быть UTF-8 (на крайняк UTF/UCS-чего-нибудь-ещё). При чтении текста из внешнего потока входная кодировка должна либо (в случае умолчания) браться из локали (на сколько я понимаю, тут так и сделано, что и вызвало негодование автора), либо не браться и считаться априори (спорно) UTF-8, либо указываться программистом явно (надеюсь такая возможность есть, иначе действительно фигня).
В 21-м веке хочется верить, что одно и то же слово будет отображено одинаково (если не говорить о шрифтах) на любой современной машине в любой стране; программируя логику хочется оперировать (не задумываясь применяя строковые операции) именно конкретными буквами (любого языка в любой комбинации), а не байтами.
Если я не прав — буду признателен на указания в чём и почему (кроме соображений экономии — о них, как я уже указал, мне известно).
0
UTF-16 и UTF-32 не устарели. У них просто немного другая ниша — быстрая обработка данных.
Вот представь, что тебе нужно изменить один символ в UTF-8 и новый символ имеет другую байтовую длину. Получается, что нужно перестроить весь массив после этого символа, что довольно затратно. Плюс к этому, размер данных нельзя посчитать исходя из количества символов (бывает важно для низкоуровневых языков).
Или посмотри на алгоритм чтения символов из UTF-8… Нельзя просто брать нужное количество байт и не париться.
Поэтому, например, Qt используют UTF-16 для своего QString.
Вот представь, что тебе нужно изменить один символ в UTF-8 и новый символ имеет другую байтовую длину. Получается, что нужно перестроить весь массив после этого символа, что довольно затратно. Плюс к этому, размер данных нельзя посчитать исходя из количества символов (бывает важно для низкоуровневых языков).
Или посмотри на алгоритм чтения символов из UTF-8… Нельзя просто брать нужное количество байт и не париться.
Поэтому, например, Qt используют UTF-16 для своего QString.
0
Проблема добавления поддержки 3го питона в библиотеки есть, но не так уж все и плохо. Новые библиотеки достаточно просто писать так, чтоб они поддерживали и 2.х, и 3.х без всяких утилит 2to3.
«Хаки вроде sys.exc_info()[1], для обхода синтактических различий, хаки конвертирования литералов во время исполнения для совместимости с 2.х и 3.x» — эти хаки не нужны, если не поддерживать 2.5. А его поддерживать imho не нужно, т.к. в него даже security-обновлений не будет больше, да и в хоть как-то актуальных ОС его нет (в предыдущем долгоиграющем red hat 2.4, а не 2.5, и это совсем другая история).
Очень многие «большие» старые библиотеки уже портированы (вот это бывает трудно, да). C-расширения можно писать не напрямую, а через ctypes, cython и тд — поддержка 3го питона тогда в них появляется более-менее автоматически. Писать C-расширения на C все равно не очень хорошо, т.к. под pypy они если и заведутся, то по-тормозному.
Армин умный чувак и в статье много хороших мыслей, но у Армина достаточно специфичные требования (компилятор шаблонов в питоний код, например), да и статья не новая, не стоит ее уж очень близко к сердцу принимать.
Я сейчас посчитал, у меня 8 штук своих open-source библиотек, которые под 2.х и 3.х работают из одного исходного кода (втч с C расширениями), + несколько чужих библиотек портировал (или помогал портировать). Писать новый код, который и там, и там работает — совсем не сложно, это просто дело привычки, и выглядит он ничем не хуже, чем код для 2.х (а часто даже и лучше, т.к. приучаешься к __future__ импортам и более новым языковым конструкциям). Портировать — сложнее, особенно большие, старые или трюкачистые, но тоже вполне реально (nltk так и не допортировал окончательно, но там большая часть тестов уже проходит, и пара глав из nltk book работает, жду помощи из-за границы теперь).
«Хаки вроде sys.exc_info()[1], для обхода синтактических различий, хаки конвертирования литералов во время исполнения для совместимости с 2.х и 3.x» — эти хаки не нужны, если не поддерживать 2.5. А его поддерживать imho не нужно, т.к. в него даже security-обновлений не будет больше, да и в хоть как-то актуальных ОС его нет (в предыдущем долгоиграющем red hat 2.4, а не 2.5, и это совсем другая история).
Очень многие «большие» старые библиотеки уже портированы (вот это бывает трудно, да). C-расширения можно писать не напрямую, а через ctypes, cython и тд — поддержка 3го питона тогда в них появляется более-менее автоматически. Писать C-расширения на C все равно не очень хорошо, т.к. под pypy они если и заведутся, то по-тормозному.
Армин умный чувак и в статье много хороших мыслей, но у Армина достаточно специфичные требования (компилятор шаблонов в питоний код, например), да и статья не новая, не стоит ее уж очень близко к сердцу принимать.
Я сейчас посчитал, у меня 8 штук своих open-source библиотек, которые под 2.х и 3.х работают из одного исходного кода (втч с C расширениями), + несколько чужих библиотек портировал (или помогал портировать). Писать новый код, который и там, и там работает — совсем не сложно, это просто дело привычки, и выглядит он ничем не хуже, чем код для 2.х (а часто даже и лучше, т.к. приучаешься к __future__ импортам и более новым языковым конструкциям). Портировать — сложнее, особенно большие, старые или трюкачистые, но тоже вполне реально (nltk так и не допортировал окончательно, но там большая часть тестов уже проходит, и пара глав из nltk book работает, жду помощи из-за границы теперь).
+7
Кстати, какие реальные кейсы написания нового кода для 2х и 3х одновременно? Почему бы не писать сразу под 3х?
+2
Я такой кейс встретил, когда разбирал работу ObjectID в MongoDB'шном BSON (имею ввиду биндинги для питона). Уж очень напоминает
#ifdef WINDOWS ...
и похожую лабуду. 0
Это смотря как писать. if PY3:… else:… — это дурной тон и почти никогда не нужно. Без ветвления 2-3 часто можно обойтись, а когда нельзя — оно выносится в отдельный модуль (типа compat.py) и не засоряет код.
pymongo (о нем ведь речь) еще недавно поддерживал (о ужас!) python 2.3, ясно-понятно там куча хаков будет даже без поддержки 3го питона. 2.4-то поддерживать невесело. По-моему писать код, совместимый с 2.3 — 2.7 посложнее будет, чем 2.6 — 3.2, и сам код жутковатым будет, в отличие от варианта 2.6-3.2.
pymongo (о нем ведь речь) еще недавно поддерживал (о ужас!) python 2.3, ясно-понятно там куча хаков будет даже без поддержки 3го питона. 2.4-то поддерживать невесело. По-моему писать код, совместимый с 2.3 — 2.7 посложнее будет, чем 2.6 — 3.2, и сам код жутковатым будет, в отличие от варианта 2.6-3.2.
0
Сейчас все еще бОльшая часть нового кода — под 2й питон пишется, и поддержка библиотекой 2го питона — большой плюс.
+1
Спасибо за перевод и публикацию! Всё, что разрабатывает Армин отличается редкой элегантностью и продуманностью. Взять хотя бы его flask и Jinja2. Поэтому многое, что он пишет в своем блоге заслуживает внимательного прочтения и дальнейшего обдумывания.
PS: Только не понятно, почему вы сократили его фамилию(?) Фамилия австрийская и читается Ронахер. С ударением на первый слог.
PS: Только не понятно, почему вы сократили его фамилию(?) Фамилия австрийская и читается Ронахер. С ударением на первый слог.
+1
Просто казалось, что «Ronacher» будет читаться как «Ронаха» по аналогии с напр. «Arbeiter» -> «Арбайта», где окончание сглатывается за счёт нисходящей интонации.
(P.S. это воспоминания из школьного немецкого, поправьте пожалуйста, если не прав).
(P.S. это воспоминания из школьного немецкого, поправьте пожалуйста, если не прав).
0
Мелкий нюанс перевода:
«Я насчитал сотню экземпляров одной заглавной буквы в этом тексте.»
В русском языке «я» далеко не всегда пишется с заглавной буквы, в отличие от английского. Поэтому людям незнакомым с английским фраза вероятно будет непонятна.
В целом же перевод хороший. Автору большое спасибо.
«Я насчитал сотню экземпляров одной заглавной буквы в этом тексте.»
В русском языке «я» далеко не всегда пишется с заглавной буквы, в отличие от английского. Поэтому людям незнакомым с английским фраза вероятно будет непонятна.
В целом же перевод хороший. Автору большое спасибо.
0
При всё моём уважении к Армину и его библиотекам/флеймвокам, он, всё-таки, истеричка. Нет, я совершенно не хочу его унизить, оскорбить или обидеть. Просто он очень испугался нововведений и тому, что нужно поддерживать две ветки своих проектов.
Его PEP-0414 вообще бредовый — ну зачем нужны эти атавизмы?
Даже не знаю, что ещё сказать… Например, имена файлов в py2 я уже лет пять, как пишу в юникоде и не вижу вообще никаких проблем. Зависимость от локали, это совершенно правильно — настраивайте свою локаль так, чтобы не было неоднозначностей.
Поддерживать 2.5… Да я и 2.6 предпочитаю не поддерживать, если для этого нужно большее, чем поставить индексы при форматировании строк (u'{0}-{1}'.format()).
В общем, делайте свои выводы из написаного, а не берите на веру.
P.S. Читал ещё полгода назад…
Его PEP-0414 вообще бредовый — ну зачем нужны эти атавизмы?
Даже не знаю, что ещё сказать… Например, имена файлов в py2 я уже лет пять, как пишу в юникоде и не вижу вообще никаких проблем. Зависимость от локали, это совершенно правильно — настраивайте свою локаль так, чтобы не было неоднозначностей.
Поддерживать 2.5… Да я и 2.6 предпочитаю не поддерживать, если для этого нужно большее, чем поставить индексы при форматировании строк (u'{0}-{1}'.format()).
В общем, делайте свои выводы из написаного, а не берите на веру.
P.S. Читал ещё полгода назад…
+1
Можно пожалуйста пример Ваших проектов, или хотя бы приблизительное сравнение по размеру пользовательской базы с проектами Армина? Это к поддержке старых версий Python.
И при чём тут имена файлов в Py2? Он про работу фс в Py3 писал.
И при чём тут имена файлов в Py2? Он про работу фс в Py3 писал.
0
Мне понравился термин «флеймвок», надо взять на вооружение.
0
Вот находятся же умники… Ещё раз перечитай статью, потом мой комментарий и подумай, что ты спросил не так.
0
Ну и что плохого в том, что строка — это набор символов Юникод, а не байтов?
Массив байтов теперь правильно называется, и прекрасно декодируется в Юникод и обратно при указании локали.
Большинство библиотек работающих с пересылкой данных по сети требуют кроме 2to3 ещё и дополнительных правок с encode() и decode() и это здорово.
Теперь мы пересылаем по сети массивы байт, а не строки, как и было задумано.
Наконец-то это древний допотопный анахронизм про то что байт = символ уходит в прошлое. Мне не нужно думать о том что такое символ, не нужно думать о кодировке, у меня есть строка и я всегда уверен что она однозначно определена.
Большое спасибо за перевод, статья интересная, хоть и излишне экспрессивная.
Массив байтов теперь правильно называется, и прекрасно декодируется в Юникод и обратно при указании локали.
Большинство библиотек работающих с пересылкой данных по сети требуют кроме 2to3 ещё и дополнительных правок с encode() и decode() и это здорово.
Теперь мы пересылаем по сети массивы байт, а не строки, как и было задумано.
Наконец-то это древний допотопный анахронизм про то что байт = символ уходит в прошлое. Мне не нужно думать о том что такое символ, не нужно думать о кодировке, у меня есть строка и я всегда уверен что она однозначно определена.
Большое спасибо за перевод, статья интересная, хоть и излишне экспрессивная.
0
URL это строка байтов или символов?
0
Байтов. Не ascii преобразовываются пуникодом.
0
Вообще-то обычная строка, либо Request:
urllib.request.urlopen(url, data=None[, timeout], *, cafile=None, capath=None)
Open the URL url, which can be either a string or a Request object.
docs.python.org/py3k/library/urllib.request.html
И это — логично!
urllib.request.urlopen(url, data=None[, timeout], *, cafile=None, capath=None)
Open the URL url, which can be either a string or a Request object.
docs.python.org/py3k/library/urllib.request.html
И это — логично!
0
С точки зрения питона да, всё верно.
0
> И это — логично!
а теперь прикиньте во что превращается аккуратное:
зы: не троллинга ради — это Армин так писал lucumr.pocoo.org/2010/5/25/wsgi-on-python-3/ :)
а теперь прикиньте во что превращается аккуратное:
url = "http://%s:%d/" % (host, port)
в p3k.зы: не троллинга ради — это Армин так писал lucumr.pocoo.org/2010/5/25/wsgi-on-python-3/ :)
0
Если host — строка, то ни во что криминальное не превращается. Всё как и раньше.
Если host — массив байт, то что мы называем «строкой» в С++ или Python 2.x, то нужно писать так:
url = «%s:%d/» % (host.decode('cp1251'), port)
Вот именно из-за аргумента в методе decode() и нельзя считать массив байт строкой. Поскольку в строке каждый элемент — символ, а в массиве байт — каждый элемент байт. Если нужно массив байт однозначно представить строкой — используйте decode(encoding).
Интерпретация чего бы то ни было строкой должна быть явной, либо вы используете __str__.
См. import this — явное лучше неявного. Не уверен в "%s" % X — не пиши.
Если host — массив байт, то что мы называем «строкой» в С++ или Python 2.x, то нужно писать так:
url = «%s:%d/» % (host.decode('cp1251'), port)
Вот именно из-за аргумента в методе decode() и нельзя считать массив байт строкой. Поскольку в строке каждый элемент — символ, а в массиве байт — каждый элемент байт. Если нужно массив байт однозначно представить строкой — используйте decode(encoding).
Интерпретация чего бы то ни было строкой должна быть явной, либо вы используете __str__.
См. import this — явное лучше неявного. Не уверен в "%s" % X — не пиши.
0
Собственно, согласен.
P.S. Кстати, вчера случайно выяснили пренеприятную вещь: urllib2 не знает, что такое пуникод и преобразование надо делать самим. :-(
P.P.S. И ещё момент… Пишите уже современно:
Это куда красивее!
P.S. Кстати, вчера случайно выяснили пренеприятную вещь: urllib2 не знает, что такое пуникод и преобразование надо делать самим. :-(
P.P.S. И ещё момент… Пишите уже современно:
url = "http://{:s}:{:d}/".format(host, port)
Это куда красивее!
0
А почему не просто
{}
вместо {:s}
?0
В ряде случаем, имхо, симпатичнее выглядит старое форматирование:
Не нужно писать скобки (для одного аргумента), вызывать метод format (опять же со скобками), и мы сразу же принудительно указываем, что выводим строку.
Хотя я конечно фанатею от конструкции
'Введите значения поля "%s": ' % field_name
Не нужно писать скобки (для одного аргумента), вызывать метод format (опять же со скобками), и мы сразу же принудительно указываем, что выводим строку.
Хотя я конечно фанатею от конструкции
'{:%Y-%d-%m %H:%M:%S}'.format( datetime.now() )
+1
мм… не так. если url это массив байтов, значит надо использовать b"":
(если что, это не работает)
url = b"http://{:s}:{:d}/".format(host, port)
(если что, это не работает)
0
Я просто не сразу уловил твой вопрос.
В общем случае, url это массив байт. Т.е. когда ты делаешь, например, http-запрос, у тебя в нём только байты.
В питоне, конечно же, он представляется массивом символов, что вполне логично и понятно.
Но на самом деле, это всё бред. Думаю, что я не сильно погрешу против истины, если заявлю, что URL, это массив ascii-сиволов. Не ascii в хосте кодируется пуникодом, а в пути — utf-8, представленным в шестнадцатиричном виде с помощью того же ascii. По крайней мере так оно работает в http.
В общем случае, url это массив байт. Т.е. когда ты делаешь, например, http-запрос, у тебя в нём только байты.
В питоне, конечно же, он представляется массивом символов, что вполне логично и понятно.
Но на самом деле, это всё бред. Думаю, что я не сильно погрешу против истины, если заявлю, что URL, это массив ascii-сиволов. Не ascii в хосте кодируется пуникодом, а в пути — utf-8, представленным в шестнадцатиричном виде с помощью того же ascii. По крайней мере так оно работает в http.
0
Нет, не так, URL — это по сути своей строка, либо Request. Зачем пихать в неё массив байт?
Если тебе прямо так необходимо сделать из строки массив байт, то используй encode(xxx) с нужной тебе кодировкой.
Правда если ты хочешь именно URL, и жаждешь самостоятельно перекодировать и отправлять байты, то тут тебя ждут отличные перспективы велосепеда. Используй строку.
Если тебе прямо так необходимо сделать из строки массив байт, то используй encode(xxx) с нужной тебе кодировкой.
"http://{:s}:{:d}/".format(host, port).encode('cp1251')
Правда если ты хочешь именно URL, и жаждешь самостоятельно перекодировать и отправлять байты, то тут тебя ждут отличные перспективы велосепеда. Используй строку.
0
это не мне необходимо, а www.python.org/dev/peps/pep-3333/#unicode-issues :)
хочу сказать, что если в python2 «суть строк» была вполне утино-однотипна, то разработчики p3k, соорудили для нас самостоятельную заморочку. что, например, в стеке wsgi приводит к нескончаемой череде этих самых decode() / encode().
хочу сказать, что если в python2 «суть строк» была вполне утино-однотипна, то разработчики p3k, соорудили для нас самостоятельную заморочку. что, например, в стеке wsgi приводит к нескончаемой череде этих самых decode() / encode().
0
Как раз нет, на уровне протокола уже нужно оперировать массивами байт. Благо методы у них примерно такие же. Зато не происходит подмена понятий байт-символ и нет этой вечной путаницы с кодировками на уровне строк, которые должны представляться однозначно на своём уровне абстракции.
0
уровни абстракции это компромисс между нужностью и удобством. и чем их меньше приходится создавать, тем лучше. как пишут в букваре, сообщение http представляет собой последовательность октетов. поэтому «массив байт» это тоже — абстракция. так вот, нужна-ли она, такая? ведь очевидно же, что в p3k удобства, в этом плане, стало меньше, а хорошо задокументированных заморочек — больше.
>>> '1' == '1'[0]
True
>>> b'1' == b'1'[0]
False
0
Как раз это здорово, что понятия символа отделили от понятия байта. То что символ можно сравнивать с односимвольной строкой — это логично, и подобное лексическое сравнение есть везде. А вот второе бред — сравнивать массив байт с байтом. Естественно False. Всё логично, как и всегда в питоне.
Что до уровней абстракции, то они всегда возникают естественным путём. В данном случае строка имеет неизмеримо высший уровень абстракции нежели массив байт. Вы же не задумываетесь о кодировке, когда что-то пишете на бумаге.
Что до уровней абстракции, то они всегда возникают естественным путём. В данном случае строка имеет неизмеримо высший уровень абстракции нежели массив байт. Вы же не задумываетесь о кодировке, когда что-то пишете на бумаге.
0
Sign up to leave a comment.
Мысли о Python 3