Литвек - электронная библиотека >> Олег Бройтман >> Python >> Питон - модули, пакеты, классы, экземпляры.

Питон - модули, пакеты, классы, экземпляры. [Олег Бройтман]

Модули - структурирование пространства имен

При создании больших программ или библиотек большим количеством людей встает проблема коллизий имен. Питон решает эту проблему так же, как и большинство современных языков - структурированием пространства имен с помощью иерархически организованных модулей.

В Питоне три пространства имен: встроенное пространство имен (им можно управлять с помощью модуля доступа к интерпретатору sys), локальное пространство функции, и глобальное пространство модуля. (Объектно-ориентированное программирование создает дополнительные пространства классов и экземпляров классов, об этом ниже). Каждое пространство имен - это список отображений имени в значение.

Модуль - это совокупность описаний, объединенных в общее пространство имен - глобальное пространство модуля. Модули подключаются к программе (или другому модулю) с помощью оператора import, после которого имена из пространства имен модуля становятся доступными. Какие именно имена становятся доступны, определяет оператор import: вариант import module делает доступным ровно одно имя - имя модуля module, но зато через это имя можно использовать все глобальные имена модуля в виде module.name. В варианте from module import name из модуля импортируется указанное имя или список имен. В варианте from module import * из модуля импортируются все имена. Хотя автор модуля может ограничить этот список, а в отсутствии такого ограничения не импортируются имена, начинающиеся с подчеркивания - считается, что это внутренние имена модуля, не входящие в его публичный интерфейс.

Модуль может быть написан на Python, C или C++. Модули, написанные на Питоне, позволяют создавать новые классы (об объектно-ориентированном программировании речь будет идти ниже). Модули написанные на C и C++ позволяют создавать новые типы данных. Модули, написанные на C/C++ могут быть встроенные (builtin) или подгружаемые (DLL в Windows, разделяемые библиотеки в тех вариантах UNIX, в которых формат выполняемых файлов ELF).

Модуль на Питоне - это текстовый файл с расширением .py, содержащий описания переменных, функций и классов, плюс выполняемый код, который позволяет инициализировать модуль. Этот код выполняется при первом импорте модуля, после чего интерпретатор запоминает, что модуль уже проимпортирован и проинициализирован, и при последующих импортах этого же модуля код инициализации не выполняется.

Модули можно объединять в древовидные иерархии. Например, пакет XML содержит в себе пакеты DOM, SAX, Parsers (и другие, в зависимости от реализации). В результате можно проимпортировать PyExpat командой import xml.parsers.expat, тогда команды этого модуля будут доступны как xml.parsers.expat.ParserCreate, а можно проимпортировать его же командой from xml.parsers import expat, тогда команды этого модуля будут доступны как expat.ParserCreate. Или сразу from xml.parsers.expat import ParserCreate!

Объектно-ориентированное программирование

Питон - объектно-ориентированный язык со множественным наследованием. Можно сказать, что Питон поддерживает классическую ОО-модель с некоторыми особенностями. Классы в Python могут иметь статические переменные, разделяемые всеми экземплярами класса, но не могут иметь статических методов. Все методы относятся к экземплярам класса. Все методы можно переопределять в наследниках. Ссылка на объект (экземпляр класса) передается в методы в явном виде, в первом параметре. Традиционно эту переменную называют self. Какого-то общего предка всех классов (типа Object) в Python нет. Вообще в ОО-программировании в Питоне важно не кто от кого наследуется, а какой поддерживается интерфейс; наследование лишь дает реализацию. Формальных механизмов проверки интерфейсов пока нет, но возможно они будут включены в язык и библиотеки; Zope делает шаги в этом направлении.

Конструктор и деструктор класса называются __init__ и __del__ (встроенные и служебные имена в Питоне обозначаются двумя подчеркиваниями перед и после имени; это всего лишь соглашение, язык не запрещает программисту писать собственные методы с такими именами). Вернее было бы назвать эти методы initializer и finalizer - они сами не размещают и не освобождают память (это делает за них интерпретатор), они инициализируют и очищают свои переменные.

В Питоне нет отдельного оператора new для создания экземпляров класса. Для создания экземпляра класса вызывается класс с необходимыми параметрами. Эти параметры передаются в __init__. Метод __del__, конечно, вызывается без параметров (кроме, естественно, self). Для удаления объектов (и не только экземпляров классов) в Питоне есть оператор del.

Пример.

class Foo:

bar = "baz"


def __init__(self, foo):

self.foo = foo


def __del__(self):

del self.foo


foo = Foo(12)

del foo

Описание класса создает новое пространство имен, в котором определяются статические переменные (в нашем примере это bar) и методы. Создание экземпляра порождает пространство имен объекта, доступ к которому осуществляется через переменную экземпляра класса foo, а внутри методов класса - через переменную self.

Классы в Питоне позволяют программисту создавать новые типы данных и определять для них все операции, доступные для встроенных типов. Например, метод __getitem__ позволяет индексировать объект, а __setitem__ - присваивать индексу объекта. Метод __getitem__ также позволяет объекту участвовать в цикле for, эмулируя последовательность (sequence). Есть методы, позволяющие объекту эмулировать булевские значения и участвовать в операторах if и while. Методы __getattr__ и __setattr__ позволяют читать и писать атрибуты объектов. Метод __call__ позволяет вызывать экземпляр класса с параметрами!

Python позволяет переопределить все инфиксные операции, причем отдельно для левого и правого аргумента выражения. Например, если a - экземпляр класса A, и b - экземпляр класса B, то для вычисления выражения a + b Питон будет сначала искать метод __add__ в классе A, а если не найдет - то метод __radd__ в классе B (а если и там не найдет - возбудит исключение TypeError).

Многие программисты, особенно писавшие на C++, боятся и не любят множественного наследования. Авторы языка Java вообще не включили множественное наследование в язык. Совершенно напрасно! Python позволяет использовать множественное наследование весьма успешно и удобно. Множественное наследование облегчает переиспользование кода (code reuse) вместо copy/paste-программирования, что очень важно и для эффективности, и для читаемости программ, и для отладки. Часто программисты на Питоне создают класс с помощью множественного наследования из нескольких связанных между собой "кирпичиков", словно из конструктора. Такие "кирпичики" в ОО-программировании называются
ЛитВек: бестселлеры месяца
Бестселлер - Влада Ольховская - Синдром Джека-потрошителя - читать в ЛитвекБестселлер - Кэтлин Эйзенхардт - Простые правила - читать в ЛитвекБестселлер - Роберт Сапольски - Биология добра и зла. Как наука объясняет наши поступки - читать в ЛитвекБестселлер - Винифред Ватсон - Один день мисс Петтигрю - читать в ЛитвекБестселлер - Анастасия Тарасова - Сам себе финансист: Как тратить с умом и копить правильно - читать в ЛитвекБестселлер - Стюарт Тёртон - Семь смертей Эвелины Хардкасл - читать в ЛитвекБестселлер - Джереми Хейманс - Новая власть. Какие силы управляют миром – и как заставить их работать на вас - читать в ЛитвекБестселлер - Александра Вадимовна Николаенко - Небесный почтальон Федя Булкин - читать в Литвек