На прошлом уроке нами была написана "серьезная" программа, которую могут использовать другие программисты. Однако как? Просто копировать код и вставлять в свои скрипты? Или есть более экономный способ (в смысле уменьшения объема кода и удобства его использования)?
При создании крупных программ оказался выгодным так называемый модульный принцип организации, когда есть основной файл с частью кода программы, к которому подсоединяется (в который импортируется) содержимое других файлов. Когда исходный код основного файла транслируется в машинный код, то импортируемые файлы также выполняются как и код основного файла.
Такой способ организации программы позволяет изолировать часто используемый код в файл-модуль, а затем импортировать его в другие файлы без копирования кода. Но это далеко не единственное преимущество модульного принципа организации программы.
Так как же импортировать содержимое одного файла в другой в языке программирования Python? Существует два основных способа: инструкция import и инструкция from. Первая инструкция запускает (интерпретирует) файл-модуль полностью, при этом для доступа к переменным (атрибутам) модуля из основного файла следует указывать имя модуля впереди требуемого атрибута: module.attribute (так называемая, точечная нотация). Инструкция from передает интерпретатору лишь указанные имена из файла-модуля, однако при доступе к этим переменным не надо указывать имя модуля. Первый способ хорош, если предстоит пользоваться содержимым почти всего модуля, второй — если будут востребованы одна-две функции или класс из модуля. В примере данного урока мы воспользуемся инструкцией import.
Импорт в языке программирования Python осуществляется следующим образом: после слова import пишется имя импортируемого модуля. Модуль и файл в Python понятия почти не различимые. Файлы с кодом на языке Python обычно имеют расширение .py, однако в инструкции import расширение не указывается. Например, если мы имеем файл-модуль scale.py, то импортировать его в другой файл следует так: import scale.
Где должен располагаться модуль? В принципе, где угодно, т.к. можно "вручную" настроить интерпретатор так, что он будет искать там, где пожелает программист. Однако, если ничего не настраивать, то интерпретатор Python найдет файлы, если их расположить например, в каталоге, куда установлен Python или в том же каталоге, где и файл, в который осуществляется импорт. Этим последним вариантом мы и воспользуемся.
Итак, у нас есть файл с кодом, позволяющим вычислять оклеиваемую площадь помещения (урок №7). Пусть он называется rooms.py. Кроме того, удалим из него "код тестирования" …
… и предположим, что классы этого модуля будут использоваться в другом (основном) файле. Допустим, этот основной файл предоставляет интерфейс пользователю для ввода данных и получения результата. Основной файл должен быть сохранен в том же каталоге, что и файл rooms.py.
Первым делом, импортируем содержимое файла rooms.py
import rooms
Далее организуем запрос данных у пользователя, одновременно преобразовав данные в целочисленный тип (функция int):
print ("Введите размеры помещения (в метрах) ...")l = int(input ("длина: "))w = int(input ("ширина: "))h = int(input ("высота: ")) print ("Введите данные об оконных проемах (в метрах) ...")h_w = int(input ("высота: "))w_w = int(input ("ширина: "))m = int(input ("количество: ")) print ("Введите данные о дверных проемах (в метрах) ...")h_d = int(input ("высота: "))w_d = int(input ("ширина: "))n = int(input ("количество: "))
Теперь создаем объект класса Room. Описание класса находится в модуле rooms, который был импортирован инструкцией import (а не from), поэтому, чтобы получить доступ к классу Room и его атрибутам, следует при создании объекта указать модуль, в котором он находится:
uroom = rooms.Room(l,w,h)
А теперь можно пользоваться атрибутами класса из модуля сколько влезет:
Создайте скрипт, импортирующий модуль с классом Room и использующий его (как показано в данном уроке).
Допишите предыдущую программу, расширив ее возможности: можно по-желанию получить дополнительные сведения (площадь окна и двери).
Переделайте программу таким образом, чтобы она не запрашивала у пользователя данные, а предлагала выбор из пяти готовых решений: на экран выводятся характеристики различных помещений, — пользователю остается только выбрать.
VII. Пример объектно-ориентированной программирования на языке Python.
В ООП очень важен этап предварительного проектирования. Вообще можно выделить следующие этапы создании ОО-программы:
Формулирование задачи.
Определение объектов, участвующих в ее решении.
Проектирование классов, на основе которых будут созданы объекты, а также установление между ними иерархических связей.
Определение существенных свойств и методов для задач, которые будут решать объекты на основе проектируемых классов.
Создание классов, описание их свойств и атрибутов.
Создание объектов.
Решение задачи путем взаимодействия объектов.
Первый этап:
Допустим нам надо написать программу про занятие, где ученики должны получить некий объем знаний.
Второй этап:
Какие объекты понадобятся? Очевидно, это ученики, учитель, информация, а также возможно вспомогательные предметы такие как проектор и др.
Третий этап:
Классы: учитель, ученик, информация. Учитель и ученик во многом похожи: по идеи оба - люди. Значит классы учитель и ученик могут принадлежать одному суперклассу - человек. Однако не все так просто. Если существенные признаки для решения данной задачи не имеют ничего общего, то выделить что-то в суперкласс просто невозможно.
Четвертый этап:
Выделим важное, чем должны обладать объекты (классы) для решения задачи «увеличить знания».
Ученик должен уметь воспринимать информацию, и превращать ее в знания.
Учитель, по крайней мере, должен уметь выбирать и транслировать информацию.
Информация должна содержать определенный набор строк символов. Должна быть предусмотрена возможность извлечения ее частей.
Пятый этап:
Класс «Информация»:
class Information: def __init__(self,info): self.info = info def extract(self,i): self.current = self.info[i] return "%s" % self.current
Объекты данного класса при создании должны содержать ту или иную информацию (содержание урока), допустим в виде списка. В классе также предусмотрен метод extract, позволяющий извлекать какую-то часть информации и возвращать ее в основную программу.
Объекты класса Pupil уже при своем создании обязаны иметь атрибут know, куда будут помещаться знания. Также предусмотрен метод take, обеспечивающий приемку информации.
Создание объектов:
Допустим в программе будет по одному объекту «Информатика» и «Учитель» и пару объектов «Ученик».
Какая в данном случае задача? Научить учеников чему-нибудь. Приступим.
t.into(inform.extract(2))p1.take(t.out())print ("1-ый ученик пока еще знает только ", p1.know) t.into(inform.extract(0))p1.take(t.out())p2.take(t.out())print ("1-ый ученик знает, что ", p1.know)print ("2-ой ученик знает, что ", p2.know)
Учитель берет с помощью метода extract объекта inform часть информации. Ученики, используя свой метод take имеют возможность получить информацию, воспроизводимую учителем (метод out объекта t).
В результате работы этой программы атрибут know учеников изменяется (если конечно те использовали метод take).