|
Это вторая статья цикла лекций.
Введение
Python - объектно-ориентированный
язык сверхвысокого уровня. Python, в отличии от Java, не требует
исключительно объектной ориентированности, но классы в Python так просто
изучить и так удобно использовать, что даже новые и неискушенные
пользователи быстро переходят на ОО-подход. Python поддерживает
множественное наследование, переопределение инфиксных операторов, причем
можно переопределить операцию как для левого операнда, так и для правого; в
версии 2.1 есть полное переопределение операторов сравнения (механизм rich
comparison для объектов, поддерживающих частичное упорядочивание, например,
матриц).
В Python имеются исключения и механизм их перехвата; таким образом
программист может построить правильную обработку ошибок и создать надежную
программу. Встроенные механизмы интроспекции позволяют опрашивать
интерфейсы объектов во время выполнения программы. Например, можно узнать
количество и имена параметров функции; эту интроспекцию использует Zope,
чтобы подготовить правильный список параметров функции при вызове ее из
web.
Из современных языков Python можно сравнить в первую очередь с Java и
Perl. Python выполняет все обещания, которые дала, но не выполнила Java.
Python очень хорошо переносим. Он работает на всех платформах, на которых
есть Java, и еще на многих. Мало найдется таких платформ, на которые Python
не перенесен. Я не говорю про UNIX и Windows, конечно - с точки зрения
переносимости куда интереснее такие платформы как Mac, Amiga, Palm, RiscOS,
AS/400 и многие другие. Для особых любителей Java есть Jython. Он состоит
из двух частей: во-первых, это интерпретатор Pyhon, написанный на Java, а
во-вторых это компилятор Python в байт-код Java. В сравнении с Perl -
Python как язык ему совершенно равномощен, но избавлен от великого
множества неприятностей и неудобств, присущих Perl. Python обладает богатой
стандартной библиотекой, плюс великим множеством модулей, доступных в
Интернете. Для пользователей Windows есть пакет win32, из которого доступны
практически все функции Windows API, DDE, COM.
Существует Русскоязычная Группа Пользователей Python и Zope. Сайт группы
расположен по адресу http://zope.net.ru/.
На список рассылки можно подписаться, послав по адресу
majordomo@list.glas.net
письмо с телом subscribe python.
Основные структуры управления
Python - вполне обычный, можно сказать, "традиционный" язык
программирования. Все привычные конструкции в языке есть - условный оператор
if, циклы for и while, функции, классы, модули, пакеты (иерархические
совокупности модулей). Нет цикла do-while и оператора case.
Из менее традиционных операторов - возбуждение исключений raise и их
перехват try-except-else и try-finally. Впрочем, исключения начинают
занимать свое место и в других современных языках, так что чем-то
революционным их назвать нельзя.
Для многих становится неожиданным, что в Питоне блочная структура
обозначается отступами, а не словами begin/end (или скобками). К этому,
однако, быстро привыкаешь, и это становится очень удобно.
Базовые типы данных
Для языка Python создано несколько интерпретаторов. В дальнейшем я буду
говорить про основной интерпретатор CPython (интерпретатор, написанный на
C).
В этом интерпретаторе базовые (встроенные) типы данных - целое, длинное
целое, вещественное, комплексное числа, строки, списки, кортежи и словари.
Целое в Питоне соответствует типу long того компилятора C, которым
скомпилирован интерпретатор. Длинное целое - это целое число потенциально
бесконечной длины; с помощью таких чисел можно производить вычисления
неограниченной разрядности; длинные целые эмулируются библиотекой,
встроенной в интерпретатор. Вещественное соответствует типу double.
Комплексные числа - это пара вещественных, записываемых в инженерной (а не
математической) нотации: 21 + 12j.
Строки - просто последовательности символов. Строки бывают ASCII и
Unicode, их можно перекодировать друг в друга. ASCII-строки можно также
перекодировать в другую кодировку (например,
koi8 <=> win1251)
Списки в качестве элементов могут содержать любые объекты. Списки
неограниченной длины, и в них можно добавлять и удалять элементы, изменяя
таким образом их длину. Списки в Питоне одномерные. Для эмуляции
многомерных массивов можно использовать списки, элементами которых являются
списки. Для эффективной обработки многомерных числовых матриц есть
дополнительный модуль расширения
Numerical Python.
Словари (ассоциативные массивы) - это отображения (mapping),
сопоставляющие уникальному ключу произвольный объект. Ключом словаря может
быть любой неизменяемый объект.
Изменяемые и неизменяемые объекты; адресная арифметика и ссылки
Объекты в Питоне бывают двух разновидностей - изменяемые и неизменяемые.
Списки, например - объекты изменяемые, их содержимое и длину можно менять.
Поскольку ключами словарей могут быть только неизменяемые объекты, в Питоне
есть специальный тип неизменяемых списков - кортежи. Числа, естественно,
объекты неизменяемые. Также неизменяемыми являются строки, в отличии от
многих других языков программирования. Хотя классы, написанные
программистами, порождают изменяемые объекты, у программиста есть
возможность написать класс, экземпляры которого могут быть ключами
словаря.
Адресной арифметики в Питоне нет. Вообще. Поэтому разименовать нулевой
указатель просто невозможно. Ссылки (указатели) в Питоне есть, но
манипулирование ими осуществляется прозрачно для программиста. В
действительности все переменные в Питоне являются ссылками на объекты;
поэтому, например, запись a = b означает "в
переменную a скопировать ссылку из переменной b". Также
списки и словари хранят не объекты, а ссылки на объекты. Присваивание и
разыменование ссылок производится автоматически.
Каждый объект в Питоне хранит счетчик ссылок, и при таком копировании
ссылки этот счетчик увеличивается. Счетчик же ссылок того объекта, на
который переменная a указывала раньше - уменьшается. Когда счетчик
достигает 0, объект считается неиспользуемым, для него вызывается
деструктор (если это экземпляр класса с деструктором), и память объекта
освобождается.
Такой механизм называется "синхронной сборкой мусора со счетчиком
ссылок". Помимо него, в Питоне есть асинхронный сборщик мусора, достоинство
которого в том, что он умеет распознавать циклические ссылки и очищать
объекты, на которые нет других ссылок (не из цикла). (Пример циклических
ссылок: l=[]; l.append(l))
Рассмотрим поподробнее питоновские ссылки. Создадим список и присвоим
его (на самом деле присвоим ссылку на него) в переменную a:
a = [21, 12, "str"]. Теперь присвоим ссылку из
a в переменную b: a = b. Изменим
список, на который ссылается a, скажем, добавим в него содержимое
другого списка: a += [2000]. На какой список ссылается
переменная b? На тот же, что и a - на список из 4 элементов.
Происходит это потому, что b все еще хранит ссылку на тот же список,
что и a. А теперь присвоим в a новый список:
a = [12, 21]. Что теперь будет в b? А все тот
же список из 4 элементов. Присваивание в a разорвало связь между
a и b. В переменной a теперь ссылка на новый список, а
в переменной b все та же ссылка на тот же список.
Если a - переменная, хранящая ссылку на список, и присваивание
b = a копирует только ссылку на тот же список, то
можно ли скопировать сам список? Короткий ответ - да, можно. Но не все так
просто. Ведь и сам список хранит не объекты, а ссылки на объекты. Должны ли
копироваться эти ссылки или должны быть продублированы и сами объекты?
Питон дает два ответа на этот вопрос: можно сделать и так, и эдак. Первый
вариант копирования называется "поверхностным", второй - "глубоким"
копированием. Глубокое копирование учитывает циклические ссылки. Классы,
написанные программистом, могут определять методы, участвующие в
копировании, тем самым "помогая" процессу копирования, для того чтобы не
включать в копирование лишней информации.
Манипуляции с неизменяемыми объектами осуществляются путем создания новых
объектов. Например, если в строке надо заменить символ, исходная строка
разбивается на две подстроки, и из них (плюс новый символ) создается новая
строка. Если в переменной a ссылка на цело число, то в результате
операции a += 1 в a окажется ссылка на новое
число.
|