python
«Обычное PHP-приложение»
Читаю Django Book (книга
In contrast, other Web development platforms couple the URL to the program. In typical PHP (https://www.php.net//) applications, for example, the URL of your application is designated by where you place the code on your filesystem.
Может мне
В итоге «обычные» (т. е. «встречающееся чаще других»)
P.S. ещё лингвисизм по отношению к PHP из той же книги:
If you’re experienced in another Web development platform, such as PHP or Java, you may be thinking, “Hey, let’s use a query string parameter!”, something like /time/plus?hours=3, in which the hours would be designated by the hours parameter in the URL’s query string (the part after the ?).
Анекдот про Python
Приходит первый элемент итератора к доктору.
— Доктор, меня все игнорируют. — next
Смешно?
Python iterstrip: itertools для чайников
Я общел рассказать как работает конструкция, которую мы, в итоге, в Ваней породили для тех, кто не знаком с itertools в Python. Для начала формулировка задачи: есть список (list) последовательности строк. В нём все поледовательности пустых строк, длиной более двух надо заменить на одну пустую строку, а пустые строке в начале и конце списка удалить.
Из [’’, 1, 2, 3, ’’, ’’, ’’, ’’, 4, ’’, ’’] мы должны получить аккуратное [1, 2, 3, ’’, 4].
Код, который получился в итоге, с некоторыми упращениями, выглядит вот так:
return list(
chain(
*(
[[''], grp][item or len(grp)<3]
for item, grp in (item, list(grp))
for item, grp in groupby(chain(['']*3, letter, ['']*3), lambda x:x))
)
)
)[1:-1]Заголовок функции я приводить не буду, чтобы не плодить отступы, в функцию входит параметр letter, который содержит обрабатываемый список, возвращается, соответственно, обработанный список. Я постараюсь обойтись без определения генераторов и итераторов, просто представьте, что данные «текут» по функциям, что позволяет их обрабатывать очень экономично, даже если они бесконечные.
Центральное место этой программы, функция groupby группирует входящий список, пользуясь результатом функции, записанной во втором параметре, как признаком группировки. Список не пересортируются, в группы объединяются данные, идущие подряд. На выходе появляется список туплов (tuples), состоящих из результата работы функции, применительно к группе и списка (точнее объекта _grouper) объединённых результатов:
[(x, list(k)) for x, k
Я тут прошёлся по списку [1, 2, 3, -4, -1, 2], объединяя его значения при помощи функции x>=0. Т. е. все подряд идущие числа с одинаковым знаком будут сгруппированы. Получится вот что:
[(True, [1, 2, 3]), (False,
сверху на groupby я навесил генератор — по сути, цикл, который проходит по всем элементам groupby, раскладывая тупл (tuple) в два элемента — x и k. Этот цикл для каждой итерации возвращает результат, форма которого записана перед циклом. Это тупл, состоящий из двух элементов: k (где записан результат группировочной функции) я оставил неизменным, а объект _grouper я преобразовал в список.
Функция chain объединяет итератор, для простоты можно пока представить, что она склеивает списки. Конструкция «[’’]*3» эквивалентна [’’, ’’, ’’] — трём пустым строкам. Таким образом, строка «for item, grp in groupby(chain([’’]*3, letter, [’’]*3), lambda x:x))» делает следующее: по итератору, состоящему из трёх пустых строк, нашего списка letter и ещё трёх пустых строк, проходит функция groupby, которая группирует элементы по самому простому признаку: «lambda x: x», т. е. группируются одинаковые элементы, далее по получившемуся списку туплов проходит цикл, каждый тупл раскладывается на два элемента: item и grp, где из grp делается список (при помощи вызова «list»).
Выше находится конструкция «[ [’’, grp] ][item or len(grp)<n]», выглядит она страшно и кажется «птичим языком», но на деле широко применяется в самых разнообразных языках, включая PHP, сейчас я её объясню. Результатом «item or len(grp)<n» будет True или False. Условие, на мой взгляд, очевидное: если строка не пустая или последовательность меньше 3, то True. True и False используются как индекс списка и выбирают, соответственно, первый или нулевой элемент массива, т. е. список, содержащий пустую строку или группу символов.
Цепочка такая:
Иcходная последовательность: [’’, ’1’, ’1’, ’’, ’’, ’’, ’3’, ’’, ’5’] Добавили с двух сторон пробельные строки: [’’, ’’, ’’, ’’, ’1’, ’1’, ’’, ’’, ’3’, ’’, ’5’, ’’, ’’, ’’] Прошли groupby и генератор: [ (’’, [’’, ’’, ’’, ’’]), (’1’, [’1’, ’1’]), (’’, [’’, ’’]), (’3’, [’3’]), (’’, [’’]), (’5’, [’5’]), (’’, [’’, ’’, ’’]) ] Прошли через условие на птичьем языке: [ [’’], [’1’, ’1’], [’’, ’’], [’3’], [’’], [’5’], [’’] ]
Далее у нас стоит chain, который принимает аргументом всё, что получилось, но с префиксом звёздочка. Chain, как я писал выше, объединяет итераторы, для простоты мы считаем, что это, с натяжкой, эквивалентно объединению списков. У нас есть список, содержащий списки. Хорошо бы эти списки склеить.
В PHP есть функция call_user_func_array, которая принимает на вход два параметра: фукнцию, которую надо вызывать и массив её параметров. В PHP я бы склеил эти списки вот так: call_user_func_array(’array_merge’, $letter). В Python делается всё то же самое, только синтаксис этого вызова другой: func(*args). Это означает, что когда будет вызвана функция func, список args станет списком её аргументов, chain принимает на вход любое количество элементов.
Таким образом мы получим вызов chain(*[ [’’], [’1’, ’1’], [’’, ’’], [’3’], [’’], [’5’], [’’] ]), что эквивалентно chain([’’], [’1’, ’1’], [’’, ’’], [’3’], [’’], [’5’], [’’]). На выходе мы получим следующий итератор, который как список выглядит вот так: [’’, ’1’, ’1’, ’’, ’’, ’3’, ’’, ’5’, ’’].
Легко заметить, что какое бы количество пробельных строк не было по краям, в конце всегда остаётся по одной. От них нам нужно избавиться. Делается это просто, в Python есть срезы, которыми я и пользуюсь: список[1: -1] означает «вернуть список с первого элемента, убрав ещё один с конца». В PHP это будет array_slice($list, 1, -1).
В итоге [’’, ’1’, ’1’, ’’, ’’, ’3’, ’’, ’5’,
Мда.
Питон — это такая змея
Меня удивляет, что некоторые программисты со рвением называют язык программирования «Пайтон» «Питоном». Безотносительно истории происхождения названия, должен заметить, что названия не переводятся. Ruby никто не называет «Рубином», язык «Си» языком «Вэ», а SmallTalk «Непринуждённой Беседой».
Python — это «Пайтон».
Python 3.0
Не знаю когда выйдет «Пайтон» версии 3 (roadmap я не смотрел), но что в нём нового мне хочется знать уже сейчас. Из всех изменений для меня наиболее непонятное замена конструкции print на функцию с тем же названием. Видимо для того, чтобы можно было её перекрыть?
Это изменение для меня лично неудобно. В дальнейшем придётся держать в голове на какой версии я пишу — 2.5 или 3.0 (в 2.6 эту функцию можно импортировать из модуля __future__). В Python 2.5 конструкция print () выведет пустой тупл (tuple), а в Python 3.0 — пустую строку. Соотвественно, print (’a’, ’b’) в 2.5 означает печать тупла со значениями ’a’ и ’b’, а в 3.0 — вывод двух строковых параметров.
Все остальные изменения одобряю со страшной силой (хотя зачем нужно было рушить синтаксис исключений мне тоже неведомо, чтобы не пересекались указания нескольких обрабатываемых исключений и переменные, куда они помещаются?).
Поиск «утечек» в Python
У home_virtualis нашёл интересную статью о поиске «утечек» в Python на практике: «Exception #08: Поиск „утечек“ памяти
Кстати, с конечным выводом статьи я бы поспорил:
Память не «утекает» в python просто так. Если в программе есть рост используемых ресурсов, то практически всегда это обозначает плохую архитектуру с необоснованно долгим сроком жизни каких либо объектов.
Что называть «Пайтоном»? Если «голый» интерпретатор, то «текущих» популярных интерпретаторов сейчас, наверное, нет. Но язык без модулей мало кому нужен. Как только подключаются внешние (скомпилированные) модули, вот тут начинаются утечки и падения. Например, у меня «Пайтон» упал уже несколько раз при попытке использования µTidylib. Один раз — при попытке открыть несуществующий файл.
Мне кажется, что стабильность интерпретатора определяется ещё и стабильностью его популярных расширений. Хоть разработчики к ним отношения могут и не иметь, но без них язык не решает популярные задачи, ради которых его и изучают.