Язык программирования Python
Язык программирования Python читать книгу онлайн
Курс посвящен одному из бурно развивающихся и популярных в настоящее время сценарных языков программирования — Python. Язык Python позволяет быстро создавать как прототипы программных систем, так и сами программные системы, помогает в интеграции программного обеспечения для решения производственных задач. Python имеет богатую стандартную библиотеку и большое количество модулей расширения практически для всех нужд отрасли информационных технологий. Благодаря ясному синтаксису изучение языка не составляет большой проблемы. Написанные на нем программы получаются структурированными по форме, и в них легко проследить логику работы. На примере языка Python рассматриваются такие важные понятия как: объектно–ориентированное программирование, функциональное программирование, событийно–управляемые программы (GUI–приложения), форматы представления данных (Unicode, XML и т.п.). Возможность диалогового режима работы интерпретатора Python позволяет существенно сократить время изучения самого языка и перейти к решению задач в соответствующих предметных областях. Python свободно доступен для многих платформ, а написанные на нем программы обычно переносимы между платформами без изменений. Это обстоятельство позволяет применять для изучения языка любую имеющуюся аппаратную платформу.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
При выделении объектов необходимо абстрагироваться (отвлечься) от большинства присущих им свойств и сконцентрироваться на свойствах, значимых для задачи..
Выделяемые объекты необязательно должны походить на физические объекты — ведь это абстракции, за которыми скрываются процессы, взаимодействия, отношения.
Удачная декомпозиция стоит многого. От нее зависят не только количественные характеристики кода (быстродействие, занимаемая память), но и трудоемкость дальнейшего развития и сопровождения. При отсутствии соответствующего опыта лучше не загадывать будущих путей развития программы, а делать ее как можно проще, под конкретную задачу.
Даже если просто перечислить все существительные, встретившиеся в описании задачи (явно или неявно), получится неплохой список кандидатов в классы.
При процедурном подходе тоже используется декомпозиция, но при объектно–ориентированном подходе производится декомпозиция не самого алгоритма на более мелкие части, а предметной области на классы объектов.
Объекты
До этой лекции объекты Python встречались много раз: ведь каждое число, строка, функция, модуль и т.п. — это объекты. Некоторые встроенные объекты имеют в Python синтаксическую поддержку (для задания литералов). Таковы числа, строки, списки, кортежи и некоторые другие типы.
Теперь следует посмотреть на них в свете только что приведенных определений. Пример:
Листинг
a = 3
b = 4.0
c = a + b
Здесь происходит следующее. Сначала имя «a» связывается в локальном пространстве имен с объектом–числом 3 (целое число). Затем «b» связывается с объектом–числом 4.0 (число с плавающей точкой). После этого над объектами 3 и 4.0 выполняется операция сложения, и имя «c» связывается с получившимся объектом. Кстати, операциями, в основном, будут называться методы, которые имеют в Python синтаксическую поддержку, в данном случае — инфиксную запись. То же самое можно записать как:
Листинг
c = a.__add__(b)
Здесь __add__() - метод объекта a, который реализует операцию + между этим объектом и другим объектом.
Узнать набор методов некоторого объекта можно с помощью встроенной функции dir():
Листинг
>>> dir(a)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__',
'__delattr__', '__div__', '__divmod__', '__doc__', '__float__',
'__floordiv__', '__getattribute__', '__getnewargs__', '__hash__',
'__hex__', '__init__', '__int__', '__invert__', '__long__',
'__lshift__', '__mod__', '__mul__', '__neg__', '__new__',
'__nonzero__', '__oct__', '__or__', '__pos__', '__pow__',
'__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__',
'__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__',
'__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__',
'__rshift__', '__rsub__', '__rtruediv__', '__rxor__',
'__setattr__', '__str__', '__sub__', '__truediv__', '__xor__']
Здесь стоит указать на еще одну особенность Python. Не только инфиксные операции, но и встроенные функции ожидают наличия некоторых методов у объекта. Например, можно записать:
Листинг
abs(c)
А функция abs() на самом деле использует метод переданного ей объекта:
Листинг
c.__abs__()
Объекты появляются в результате вызова функций–фабрик или конструкторов классов (об этом ниже), а заканчивают свое существование при удалении последней ссылки на объект. Оператор del удаляет имя (а значит, и одну ссылку на объект) из пространства имен:
Листинг
a = 1
# …
del a
# имени a больше нет
Типы и классы
Тип определяет область допустимых значений объекта и набор операций над ним. В ООП тип тесно связан с поведением — действиями объекта, состоящими в изменении внутреннего состояния и вызовами методов других объектов.
Ранее в языке Python встроенные типы данных не являлись экземплярами класса, поэтому считалось, что это были просто объекты определенного типа. Теперь ситуация изменилась, и объекты встроенных типов имеют классы, к которым они принадлежат. Таким образом, тип и класс в Python становятся синонимами.
Интерпретатор языка Python всегда может сказать, к какому типу относится объект. Однако с точки зрения применимости объекта в операции его принадлежность к классу не играет решающей роли: гораздо важнее, какие методы поддерживает объект.
Примечание:
Пока что в Python есть «классические» и «новые» классы. Первые классы определяются сами по себе, а вторые обязательно ведут свою родословную от класса object. Для целей данного изложения разница между этими видами классов не имеет значения.
Экземпляры классов могут появляться в программе не только из литералов или в результате операций. Обычно для получения объекта класса достаточно вызвать конструктор этого класса с некоторыми параметрами. Объект–класс, как и объект–функция, может быть вызван. Это и будет вызовом конструктора:
Листинг
>>> import sets
>>> s = sets.Set([1, 2, 3])
В этом примере модуль sets содержит определение класса Set. Вызывается конструктор этого класса с параметром [1, 2, 3]. В результате с именем s будет связан объект–множество из трех элементов 1, 2, 3.
Следует заметить, что, кроме конструктора, определенные классы имеют и деструктор — метод, который вызывается при уничтожении объекта. В языке Python объект уничтожается в случае удаления последней ссылки на него либо в результате сборки мусора, если объект оказался в неиспользуемом цикле ссылок. Так как Python сам управляет распределением памяти, деструкторы в нем нужны очень редко. Обычно в том случае, когда объект управляет ресурсом, который нужно корректно вернуть в определенное состояние.
Еще один способ получить объект некоторого типа — использование функций–фабрик. По синтаксису вызов функции–фабрики не отличается от вызова конструктора класса.
Определение класса
Пусть в ходе анализа данной предметной области необходимо определить класс Граф. Граф — это множество вершин и набор ребер, попарно соединяющий эти вершины. Над графом можно проделывать операции, такие как добавление вершины, ребра, проверка наличия ребра в графе и т.п. На языке Python определение класса может выглядеть так:
Листинг
from sets import Set as set # тип для множества
class G:
def __init__(self, V, E):
self.vertices = set(V)
self.edges = set(E)
def add_vertex(self, v):
self.vertices.add(v)
def add_edge(self, (v1, v2)):
self.vertices.add(v1)
self.vertices.add(v2)
self.edges.add((v1, v2))
def has_edge(self, (v1, v2)):
return (v1, v2) in self.edges
def __str__(self):
return "%s; %s» % (self.vertices, self.edges)
Использовать класс можно следующим образом:
Листинг
g = G([1, 2, 3, 4], [(1, 2), (2, 3), (2, 4)])
print g
g.add_vertex(5)
g.add_edge((5,6))
print g.has_edge((1,6))
print g
что даст в результате
Листинг
Set([1, 2, 3, 4]); Set([(2, 4), (1, 2), (2, 3)])
False
Set([1, 2, 3, 4, 5, 6]); Set([(2, 4), (1, 2), (5, 6), (2, 3)])
Как видно из предыдущего примера, определить класс не так уж сложно. Конструктор класса имеет специальное имя __init__. (Деструктор здесь не нужен, но он бы имел имя __del__.) Методы класса определяются в пространстве имен класса. В качестве первого формального аргумента метода принято использовать self. Кроме методов в объекте класса имеются два атрибута: vertices (вершины) и edges (ребра). Для представления объекта G в виде строки используется специальный метод __str__().
Принадлежность классу можно выяснить с помощью встроенной функции isinstance():