Интимное знакомство с PythonАлексей Черкес (aleksei.cherkes@gmail.com) «С момента основания Python был важной частью Google, и остается ей по мере того, как система растет и развивается. Множество инженеров Google используют Python, и мы ищем больше людей, умеющих с ним работать» (Peter Norvig, директор по исследованию качества, Google, Inc.) Еще в январе ты мог заметить, что мы стали посвящать определенное количество журнального пространства замечательному языку программирования под названием «Python». С этого выпуска мы будем публиковать по две тематических статьи за номер: первая – для тех, кто только начинает изучать этот рулезный язык, а вторая – для более-менее продвинутых программеров. Кстати, и Горл, и Никитос – оба записные фанаты Питона ;). Итак, Python - это высокоуровневый мультипарадигменный язык программирования c динамической типизацией. Он относится к языкам общего назначения. Главный акцент в языке делается на чистоту и читабельность синтаксиса, легкое освоение, минималистичный дизайн, целостную архитектуру. Благодаря этому, программы на Python быстро разрабатываются и легко сопровождаются. Исходный текст в 2, а то и 10 раз короче, чем код аналогичной программы на Java. Let's play!Давай запустим интерпретатор Python и немного поиграемся. В статье не будет пространных примеров и объяснений – просто куски кода для скорого ознакомления с языком. Что же мы видим? За символами «>>>» идет текст, вводимый в интерпретатор. После него - ответ интерпретатора (результат вычисления введенного выражения).
Получается, интерпретатор можно использовать вместо инженерного калькулятора на лампах накаливания :).
Вместо символа подчеркивания подставляется последнее выведенное значение. Поддерживается арифметика с вещественными, комплексными числами. Разумеется, «длинная арифметика» тоже поддерживается. Основы основЧеловеку, знакомому с С-подобными языками, синтаксис Python может показаться очень необычным, ведь внешний вид основных операторов Python отличается от своих аналогов в других языках. Это нестрашно, ибо кажущаяся необычность синтаксиса не умаляет его достоинств - систематичности и последовательности. Привыкание наступает быстро - буквально после первых десятков написанных строк язык будет восприниматься не хуже родного. Python очень продуман и минималистичен, что отнюдь не мешает ему обладать мощностью и гибкостью. Для базового знакомства с возможностями этого зеленого змия достаточно пары-тройки вечеров. Рассмотрим пример:
Первое, что бросается в глаза - использование табуляций или пробелов (но не того и другого вместе!) для обозначения блоков операторов (в С, напомню, используются фигурные скобки). В тело цикла входит две строки. Сперва это непривычно, но на самом деле – чертовски удобно! Самое главное, что сам язык определяет единый стиль кодирования. Прошу заметить, больше не возникает многостраничных холиваров на форумах о том, где все-таки нужно ставить скобочку. Код автоматически становится хорошо читаемым. Еще одна из мелочей, обуславливающих популярность Python - это кортежи. Обрати внимание, как в примере присваиваются значения переменным. Переменные, перечисленные через запятую, образуют кортеж. Кортежи - это что-то вроде неизменяемых массивов. Их можно присваивать друг другу (как в примере). Чтобы в Python поменять местами значение двух переменных x и y, необязательно вводить третью временную переменную. Достаточно лишь написать x, y = y, x!
В Python цикл for умеет перебирать только элементы коллекций (в некоторых языках для этого есть foreach). Очень изящное решение, не правда ли? List - это список из четырех строк. Мы перебираем их в цикле, выводя на экран. Итерироваться можно не только по встроенным коллекциям. Любой объект, предоставляющий интерфейс итератора, можно писать вместо нашего списка list. А такие объекты встречаются довольно часто, например, итерируясь по объекту открытого файла, мы будем получать строки в нем. Задача печати всех строк в файле займет на одну строку больше, чем этот пример (файл нужно еще закрыть). Перебор диапазона целых чисел (как это обычно делалось в С) - это частный случай описанной схемы. Есть функция range(), которая возвращает коллекцию-диапазон. К важным фишкам языка относятся также встроенные коллекции: словари (пары ключ-значение), списки (динамические массивы), кортежи (близки к неизменяемым спискам), строки (что-то вроде списка символов) и множества (неиндексируемые коллекции неповторяющихся элементов). Для работы с ними существует много функций, методов и специальных синтаксических средств. Все коллекции, кроме строк, являются гетерогенными (в них можно хранить объекты разных типов данных, включая другие коллекции). Благодаря богатству, функциональности и простоте использования, они становятся кирпичиками твоих программ. Ты уже не думаешь в терминах низкоуровневых циклов и переменных-счетчиков, не забиваешь себе голову мыслями о выделении и освобождении памяти и т.п. Алгоритм обычно записывается так, каким он и представляется - наглядно и лаконично. Играемся с функциямиФункции в Python являются объектами первого класса. Это значит, что их можно использовать в программе безо всяких ограничений, подобно объектам простейших типов (числа, коллекции и т.п.). Функции могут иметь разную область видимости (локальные, глобальные), передаваться в другие функции как параметры и возвращаться из них. Память под функции выделяется, как и для других объектов. Если на функцию закончились ссылки, ее код удаляется сборщиком мусора. Попробую объяснить на примере:
Здесь демонстрируется сразу несколько особенностей языка. Рассмотрим их подробнее.
В Python можно создавать анонимные (безымянные) функции. Еще они называются lambda-функциями (есть раздел математики, называемый lambda-исчислением, который служит теоретической основой для функционального программирования). Значение выражения lambda x: x**a - это функция, имеющая один параметр x и возвращающая этот параметр, возведенный в степень а (** - оператор возведения в степень). Имя этой новой функции присваивается в точке вызова make. Если этого не сделать, она просто будет удалена сборщиком мусора. В данном примере наша анонимная функция использует внешнюю переменную «a», хотя она и не передается в нее как параметр. Когда анонимная функция создается внутри make, для нее будет создано замыкание. В него войдет эта функция и значение переменной «а». Если пользователь вызовет эту функцию, значение «a», необходимое для работы, будет извлечено из замыкания и использовано. С каждым новым вызовом функции make создается новое замыкание с разными значениями «a». Назначение функции make - создавать другие функции (!), которые возводят свой единственный аргумент в степень «а». Этот пример лучше освоить, прежде чем читать дальше :). Как было указано выше, Python - мультипарадигменный язык. Помимо всего прочего, он содержит элементы аспектно-ориентированного программирования (АОП). Об этой парадигме говорят, когда традиционные средства ООП в программе не позволяют выделить некоторую функциональность в отдельный объект или модуль. Такую функциональность называют сквозной. Классические примеры: трассировка вызовов, проверка инвариантов функции (пред- и пост- условия вызова), обработка ошибок и т.п. В программах, написанных на более традиционных языках, изменение функциональности, по которой не происходило разбиение программы на объекты (сквозной функциональности), требует больших затрат, поскольку такие изменения задевают большие участки кода. Декораторы в Python - вот способ решения проблемы. Декоратор – играет роль своеобразной обертки для метода. Рассмотрим пример:
Функция foo помечена декоратором @logger. Декоратор - это функция или класс, предназначенный для изменения других функций. Например, применение декоратора @logger к функции foo эквивалентно следующей записи: foo = logger(foo). То есть, настоящей функцией foo становится то, что декоратор @logger вернет, получив на вход нашу foo. Это несложный декоратор, который просто трассирует вызовы функций, выводя на консоль сообщения о входе и выходе из них. Если трассировку нужно выключить, можно заменить декоратор на такой: def logger(f): return f. В других языках такая задача может стать серьезной проблемой, но здесь все делается буквально в два счета ООПНесмотря на то, что Python - объекто-ориентированный язык, некоторые аспекты его ООП-модели могут показаться необычными из-за ее динамических свойств. Часто услышать выражение «утиная типизация». Python считает, что, если объект крякает, как утка, и летает, как утка, то можно считать его уткой. Объект тут можно сравнить с мешком для всякого барахла. Содержание мешка определяется во время выполнения программы. В объект можно засовывать дополнительные поля, добавлять методы, заменять их – в общем, делать все, что душе угодно. Конструктор класса создает пустой мешок, запихивает туда кое-какие методы и возвращает программисту. При этом нет возможности узнать, каким классом был сделан мешок, поскольку все мешки «внешне» одинаковые и различаются только содержанием. Когда интерпретатор видит выражение типа obj.f(), он берет мешок с именем obj, роется в нем и, если таковой найдется, выполняет метод f. Если нет – прими ошибку времени выполнения. Это и есть динамическая типизация. Python поддерживает полную интроспекцию. В мешке разрешено рыться сколько душе угодно! В нем даже может храниться документация к объекту. Более того, сами классы - это тоже объекты! И их тоже можно менять во время выполнения. Так мы приходим к важной концепции метаклассов, но ее мы рассмотрим как-нибудь в другой раз. Кстати, забыл добавить - Python обладает хорошим механизмом обработки исключений. Программу легко разбивать на модули (модули - это такие же мешки!). Хорошие программы часто пишут вообще без введения пользовательских классов. Такой подход обеспечивает возможность разбиения программы на модули, замыкания, генераторы и другие высокоуровневые элементы языка. Поставляется с батарейкамиОбщие принципы дизайна Python - простота и эффективность – распространяются и на его стандартную библиотеку. Говорят, что Python поставляется с «батарейками в комплекте» (Batteries Included). Действительно, стандартная реализация (CPython) включает в себя большое множество библиотек, активно применяемых в повседневном кодинге. Просто перечислю:
И это только стандартная библиотека, которая идет в одной поставке с интерпретатором! Сложно найти область программирования, в которой нельзя было бы использовать Python. Для решения более сложных задач написано огромное количество сторонних модулей и библиотек. Самое главное, что подавляющее их большинство переносимо на все платформы, на которых работает интерпретатор. Программа на Python, использующая эти модули, будет работать в разных ОС без изменений в коде! Все это превращает Python в идеальное средство для быстрой и эффективной разработки приложений. ВыводыСегодня на Python работают тысячи приложений – как большие, сложные и критически важные для ведения бизнеса системы, так и мелкие подручные утилиты, короткие скрипты-эксплойты. Очаровав многих программистов, Python с каждым днем становится все популярнее. Надеюсь, из статьи ты понял, почему большая часть редакции ][акера уже проголосовала за этот язык программирования :). Основные реализацииСуществует довольно много интерпретаторов Python от разных организаций. Ниже приведены основные:
WWW
|