пятница, 15 мая 2009 г.

Краткая хронология Python

Разработка Python велась в то время, когда многие динамические языки программирования с открытыми исходными кодами, такие как Tcl, Perl, и (гораздо позже) Ruby также активно разрабатывались и завоевывали популярность. Чтобы помочь взглянуть на Python в исторической перспективе, ниже приведен список релизов Python. Самые ранние даты приблизительные, так как я не делал последовательные записи всех событий.

Дата релизаВерсия
Декабрь 1989Начало реализации
1990Внутренний релиз в CWI
20 Февраля, 19910.9.0 (релиз выложен в alt.sources)
Февраль, 19910.9.1
Осень, 19910.9.2
24 Декабря, 19910.9.4
2 Января, 19920.9.5 (только для Mac)
6 Апреля, 19920.9.6
1992 месяц неизвестен0.9.7 бета
9 Января, 19930.9.8
29 Июля, 19930.9.9
26 Января, 19941.0.0
15 Февраля, 19941.0.2
4 Мая, 19941.0.3
14 Июля, 19941.0.4
11 Октября, 19941.1
10 Ноября, 19941.1.1
13 Апреля, 19951.2
13 Октября, 19951.3
25 Октября, 19961.4
3 Января, 19981.5
31 Октября, 19981.5.1
13 Апреля, 19991.5.2
5 Сентября, 20001.6
16 Октября, 20002.0
17 Апреля, 20012.1
21 Декабря, 20012.2
29 Июля, 20032.3
30 Ноября, 20042.4
16 Сентября, 20062.5
1 Октября, 20082.6
3 Декабря, 20083.0

Я добавил ссылки на релизы, которые до сих пор анонсируются на python.org в настоящее время. Заметьте, что большинство релизов сопровождаются микро-релизами, например, 2.0.1; я не утруждался включать их в таблицу, иначе она получилась бы слишком длинной. Архивы с исходниками доступны здесь: http://python.org/ftp/python/src. Различные устаревшие бинарные релизов и другие старинные штучки могут быть найдены уровнем выше на этом же FTP — сервере.

Оригинал: A Brief Timeline of Python

четверг, 7 мая 2009 г.

Принципы проектирования Python

Дальнейшие записи в этом блоге опустятся в окровавленные пучины истории Python. Однако, прежде чем это сделать, я хотел бы остановиться на философских принципах которые помогали мне проектировать и реализовывать Python.

Прежде всего, Python изначально задумывался как персональный проект «опытной мастерской» — без официального бюджета. Плюс я хотел получить результаты быстро, в частности для того, чтобы убедить руководство поддержать проект (в чем я преуспел). Это привело меня к нескольким, экономящим время правилам:
  • Заимствуй идеи откуда угодно когда это целесообразно.
  • «Вещи должны быть настолько простыми насколько это возможно, но не проще» (Эйнштейн).
  • Делай одну вещь, но хорошо («Философия UNIX»).
  • Не слишком беспокойся о производительности — планируй оптимизацию на тот момент когда она понадобится.
  • Не борись со средой, плыви по течению.
  • Не стремись к совершенству, потому что зачастую «нормально» бывает достаточно.
  • (Следовательно) нормально иногда срезать углы, особенно, если позднее сможешь это исправить.
Остальные принципы применялись не ради экономии времени. Причем зачастую они приводят к прямо противоположному эффекту.
  • Реализация Python не должна быть привязанна к определенной платформе. Ничего, если некоторая функциональность будет не всегда доступна, но вот ядро должно работать везде.
  • Не обременяй пользователей детальными описаниями того, с чем машина может работать (я не всегда следовал этому правилу и некоторые из катастрофических последствий этого описаны ниже).
  • Поддерживай и вдохновляй платформо-независимый пользовательский код, но не закрывай доступ к платформенным возможностям или свойствам (это резко контрастирует с Java).
  • Большая сложная система должна иметь несколько уровней расширяемости. Это даёт пользователям больше возможностей, независимо от их опыта.
  • Ошибки не должны быть фатальными. Это означает, что код пользователя должен иметь возможность продолжать выполняться даже при ошибочных параметрах, и при условии что виртуальная машина всё еще работает.
  • В тоже время ошибки не должны оставаться незамеченными (последние два принципа привели к решению использовать механизм исключений во всей реализации).
  • Баг в пользовательском Python-коде не должен приводить к непредсказуемому поведению интерпретатора; ошибка ядра не может быть виной пользователя.
Наконец, у меня были разнообразные идеи, касающиеся хорошего проектирования языка программирования. Во многом, они были приобретены мною в «ABC group», где я получил первый настоящий опыт проектирования и реализации языков программирования. Сложнее всего выразить эти идеи словами, так как во многом они зависят от таких субъективных понятий как элегантность, простота и удобочитаемость.

Несмотря на то, что о влиянии «ABC» на Python я собираюсь рассказать немного позже, хотелось бы особо отметить одно правило удобочитаемости: символы пунктуации следует использовать консервативно, подобно тому как они используются в письменном английском или в школьной алгебре. Исключения были сделаны для тех случаев, когда определенная форма записи является давней традицией в языках программирования, как, например, «x*y» для умножения, или «a[i]» для указания индекса в массиве, или «x[foo]» для выборки атрибутов. При этом в Python не используется «$» для обозначения переменных и «!» для обозначения операций с побочным эффектом.

Тим Питерс (Tim Peters), давно использующий Python, и который в стал самым упорным и продуктивным разработчиком ядра, попробовал изложить мои несформулированные принципы проектирования в том, что он назвал «Дзен Python». Я процитирую его здесь полностью:
  • Красивое лучше уродливого.
  • Явное лучше неявного.
  • Простое лучше сложного.
  • Сложное лучше усложнённого.
  • Плоское лучше вложенного.
  • Разрежённое лучше плотного.
  • Удобочитаемость важна.
  • Частные случаи не настолько существенны, чтобы нарушать правила.
  • При этом практичность важнее безупречности.
  • Ошибки никогда не должны возникать незаметно.
  • За исключением незаметности, которая задана явно.
  • В случае двусмысленности откажитесь от соблазна попытаться угадать.
  • Должен существовать один — и, желательно, только один — очевидный способ сделать это.
  • Даже если этот путь с первого взгляда может быть не очевиден (особенно если вы не голландец).
  • «Сейчас» лучше, чем «никогда».
  • При этом «никогда» часто бывает лучше, чем «прямо сейчас».
  • Если реализацию сложно объяснить — то в ее основе плохие идеи.
  • Если реализацию легко объяснить — то в ее основе может быть хорошая идея.
  • Пространства имён — великолепная идея. Давайте сделаем их больше!
Несмотря на то что мой опыт работы в ABC оказал сильное влияние на Python, «ABC group» имела несколько принципов проектирования, радикально отличавшихся от используемых мной в Python. Разными способами, но в Python совершён сознательный уход от следующих идей:
  • «ABC group» во всем стремилась к совершенству. Например, они использовали алгоритмы, где данные представлены древовидной структурой, и которые считаются оптимальными для асимптотически больших коллекций (при этом не так хороши маленьких).
  • В «ABC group» хотели, насколько это возможно, изолировать пользователя от «большого и страшного мира компьютеров». Мало того что должны отсутствовать ограничения на диапазоны числовых значений, длины строк и размеры коллекций (не считая ограничения доступной оперативной памяти). У пользователей не должна была возникать необходимость работать с файлами, дисками, «сохранением» или другими программами. Эти стремления подвигли «ABC group» создать полностью интегрированную среду редактирования. (Конечно были возможности избежать ABC окружение, но, преимущественно, они были запоздалые и не были доступны напрямую из языка).
  • В «ABC group» исходили из предположения о том, что пользователи ранее не имели опыта работы с компьютером (или были готовы забыть его). Поэтому была введена альтернативная терминология — более «дружественные к новичкам» стандартные термины программирования. Например, процедуры были названы «инструкциями» (how-tos), а переменные «положениями» (locations).
  • «ABC group» разрабатывали язык ABC, не задумываясь о перспективах его развития, и не ожидая участия пользователей в его проектировании. Язык ABC был создан как закрытая система, безукоризненная настолько, насколько это удалось проектировщикам. Любопытство пользователей к тому, «что же там внутри», не поощрялось. И хотя были разговоры об открытии продвинутым пользователям части реализации, на более поздних стадиях проекта это так и не осуществилось.
Принципы проектирования, использованные мной при создании Python, вероятно, стали одной из причин его конечного успеха. Вместо борьбы за совершенство, люди, впервые использовавшие Python, сочли его «достаточно подходящим» для реализации их целей. Поскольку число пользователей росло, то предложения по улучшению постепенно вносились в язык. Как вы увидите из дальнейших записей, многие из этих улучшений повлекли существенные изменения и исправления в ядре языка. И даже сегодня Python продолжает развиваться.

Оригинал: The History of Python - Python's Design Philosophy

пятница, 1 мая 2009 г.

Введение и обзор

Введение

Python, наряду с Perl, Tcl, PHP и новичком Ruby, является одним из самых популярных динамических языков программирования. Несмотря на то что его часто рассматривают язык сценариев, на самом деле это язык программирования общего назначения, как Lisp или Smalltalk (и как все остальные). Сегодня Python применяется очень широко, начиная от скриптов «написал-забыл» до больших масштабируемых веб-серверов, которые предоставляют бесперебойные сервисы 24 часа 7 дней в неделю. Он используется для программирования GUI, баз данных, клиентского и серверного веб-программирования, а также для тестирования приложений. Он используется учеными, пишущими приложения для самых быстрых суперкомпьютеров и детьми для обучения программированию.

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

Благодарности: я признателен Дейву Бизли (Dave Beazley) за большое количество отличных идей для этого блога. (Более подробно о происхождении этого блога смотрите в другом моем блоге).

Python с высоты птичьего полета

Когда кто-то сталкивается с Python, то зачастую он бывает поражен тем, как выглядит код Python. На первый взгляд, он похож на код других традиционных языков программирования, таких как C или Pascal. Это не случайно — синтаксис Python активно заимствован из C. Например, многие ключевые слова (if, else, while, for и др.) такие же как в C; у идентификаторов в Python такие же правила именования как и в C; большинство стандартных операторов имеют такое же значение как в C. Очевидно, что Python это не C, и главная область различий заключается в использовании отступов вместо скобок для группировки составных операторов. Вместо написания групповых операторов в C, например таких как эти:
if (a < b) {
max = b;
} else {
max = a;
}
Python вполне обходится без скобок (в большинстве случаев и без завершающих точек с запятой) и использует следующую конструкцию:
if a < b:
max = b
else:
max = a
Другая важная область в которой Python отличается от C-подобных языков — использование динамической типизации. В C, переменные всегда должны быть объявлены явным образом с указанием типа, такого например, как int или double. Эта информация нужна для выполнения статистических проверок на этапе компиляции программы и для выделения области памяти для хранения значения переменной. Переменные в Python — это простые имена ссылающиеся на объекты. Переменные не нужно объявлять перед присваиванием и их тип можно изменить даже в середине программы. Как и в других динамических языках, все проверки типов производятся интерпретатором на этапе выполнения, вместо проверок на шаге обособленной компиляции.

Основными встроенными типами Python являются булев, числовой (машинные целые числа, целые числа произвольной точности, вещественные и комплексные числа с плавающей запятой), и строковый (8-битные и юникод-строки). Все эти типы являются неизменяемыми, т.е. значения, представляемые объектами невозможно изменить после их создания. Соединения встроенных типов представляют кортежи (неизменяемые массивы), списки (расширяемые массивы) и словари (хеш-таблицы).

Для организации программ, Python поддерживает пакеты (группы модулей и/или пакетов), модули (связанный код сгруппирован в один файл), классы, методы и функции. Для управляющей логики, предоставлены if/else, while и высокоуровневое выражение for, перебирающее все значения «перечисляемого» объекта. Для обработки ошибок в Python использует (безвозвратные) исключения. Групповой оператор инициирует исключение, а try/except/finally конструкция определяет то как это исключение будет обрабатываться. Встроенные операторы вызывают исключения, когда сталкиваются с ошибочными условиями.

В Python, о всех объектам которые могут именоваться, говорят что они являются объектами «первого класса». Это означает что функции, классы, методы, модули и все остальные именованные объекты, могут свободно передаваться вокруг, проверяться и помещаться в различные структуры данных (например, в списки или словари) во время выполнения. Продолжая разговор об объектах, замечу что в Python реализована полная поддержка объектно-ориентированного программирования, включая классы определенные пользователем, наследование и связывание методов во время выполнения.

Python имеет богатую стандартную библиотеку, которая является одной из главных причин его популярности. Стандартная библиотека имеет более 100 модулей и постоянно развивается. Некоторыми из этих модулей включают поиск по регулярным выражениям, стандартные математические функции, потоки, интерфейсы операционной системы, сетевое программирование, стандартные интернет-протоколы (HTTP, FTP, SMTP и др.), работу с почтой, обработку XML, HTML парсинг и наборы GUI инструментов (Tcl/Tk).

В дополнение ко всему, есть еще огромное количество сторонних пакетов и модулей, большинство из которых представляют ПО с открытым исходным кодом. Здесь можно найти веб фреймворки (слишком много перечислять!), GUI инструменты, и эффективные численные библиотеки (включая оболочки для многих популярных Fortran-пакетов), интерфейсы к реляционным базам данных (Oracle, MySQL и другим), SWIG (утилита для использования произвольных библиотек C++ в качестве модулей в Python), и многое другое.

Главной привлекательностью Python (как и других динамических языков в этом же отношении) является то, что казалось бы сложные задачи зачастую могут решены очень маленьким количеством кода. В качестве примера я приведу простой Python скрипт, который получает веб-страницу, сканирует ее для поиска URL-ссылок, и выводит на экран первые 10 таких ссылок.
# Сканирование веба для поиска ссылок

import re
import urllib

regex = re.compile(r'href="([^"]+)"')

def matcher(url, max=10):
«Печатаем первые несколько ссылок для переданного URL.»
data = urllib.urlopen(url).read()
hits = regex.findall(data)
for hit in hits[:max]:
print urllib.basejoin(url, hit)

matcher("http://python.org")
Эта программа может быть легко модифицирована для создания поискового робота. В самом деле, Скотт Хассан (Scott Hassan) рассказывал мне что он написал первого робота для Google на Python. Сегодня Google использует миллионы строк Python кода для управления многими аспектами своей деятельности — от автоматизации сборок до управления рекламными объявлениями (Оговорка: в настоящее время я являюсь сотрудником Google).

Под обложкой, Python реализован обычным образом — используя комбинацию байт-код компилятора и интерпретатора. Компиляция происходит неявно при загрузке модулей, и для некоторых языковых конструкций компилятор нужен во время исполнения. Хотя стандартная реализация Python де-факто написана на C и доступна для любой аппаратной/программной платформы, несколько альтернативных реализаций приобрели популярность. Jython — версия, которая работает в JVM, и имеет бесшовную интеграцию с Java. IronPython — вариант для платформы Microsoft .NET, который имеет интеграцию аналогичную другим языкам использующимся в .NET . PyPy оптимизированный компилятор/интерпретатор Python, написанный на нем же самом (проект, финансируемый EU фондом, все еще в разработке). Также есть Stackless Python, вариант реализации на C, уменьшающий зависимость вызовов функций/методов от стека, и позволяющий использовать параллельные последовательности команд, возобновления, и микропотоки.

Оригинал: Introduction and Overview