3.3.7. Обработка контекста с ключевым словом withБолее элегантный способ реализации паттерна try-except-fnally основан на ис-пользовании ключевого слова with и менеджера контекста. Python определяет менеджеров контекста для таких операций, как работа с файлами, но разработчик может определять собственных менеджеров контекста. Одно из преимуществ менеджеров контекста заключается в том, что они могут определять (и обычно определяют) завершающие действия по умолчанию, которые выполняются всегда независимо от того, происходило исключение или нет. В листинге 3.2 показано открытие и чтение файла с использованием with и менед-жера контекста.
Листинг 3.2. Файл with.py
filename = "myfile.txt"
with open(filename, "r") as f:
for line in f:
print(f)
Здесь ключевое слово with создает менеджера контекста, который инкапсулирует функцию open и следующий за ней блок. В данном случае заранее определенное завершающее действие менеджера контекста закроет файл, даже если произошло исключение, поэтому при условии, что выражение в первой строке будет выполнено без исключения, файл всегда будет закрыт. Этот код эквивалентен следующему: filename = "myfile.txt"
try:
f = open(filename, "r")
for line in f:
print(f)
except Exception as e:
raise e
finally:
f.close()
3.4. Создание модуля
Вы можете легко создавать собственные модули, которые импортируются и ис-пользуются точно так же, как модули встроенных библиотек Python. В листинге 3.3 создается простой модуль с одной функцией, которая предлагает пользователю ввести имя файла и подсчитывает количество вхождений слов в этом файле. Листинг 3.3. Файл wo.py
"""Модуль wo. Содержит функцию: words_occur()"""
# Функции интерфейса
def words_occur():
"""words_occur() - подсчитывает вхождения слов в файле.""" # Запросить у пользователя имя файла.
file_name = input("Enter the name of the file: ")
# Открыть файл, прочитать его и сохранить слова в списке. f = open(file_name, 'r')
word_list = f.read().split()
f.close()
# Подсчитать количество вхождений каждого слова в файле. occurs_dict = {}
for word in word_list:
# Увеличить счетчик для данного слова.
occurs_dict[word] = occurs_dict.get(word, 0) + 1
# Вывести результаты.
print("File %s has %d words (%d are unique)" \
% (file_name, len(word_list), len(occurs_dict))) print(occurs_dict)
if __name__ == '__main__':
words_occur()
Строки документации — стандартный способ документирования модулей, функций, методов и классов . Комментарий состоит из всех символов, начинающихся с # . Функция read возвращает строку, содержащую все символы в файле , а функция split возвращает список слов строки, «разбитой» по символам-пропускам. Сим-вол \ позволяет продолжить длинную команду в нескольких строках программы . Эта команда if позволяет выполнить программу как сценарий, для чего следует ввести команду python wo.py в командной строке . Если разместить файл в одном из каталогов, входящих в путь поиска модулей из переменной sys.path , его можно будет импортировать командой import точно так же, как любой встроенный библиотечный модуль:
>>> import wo
>>> wo.words_occur()
Функция вызывается с тем же синтаксисом атрибутов, который используется для функций библиотечных модулей.
Обратите внимание: если изменить файл wo.py на диске, команда import не отразит эти изменения в том же интерактивном сеансе. В таких ситуациях можно восполь-зоваться функцией reload из библиотеки imp :
>>> import imp
>>> imp.reload(wo)
Для больших проектов существует обобщение концепции модуля — пакеты по-зволяют легко группировать модули в каталоге или дереве подкаталогов, чтобы затем импортировать и использовать для обращения к ним иерархические ссылки вида пакет.субпакет.модуль . В сущности, для этого потребуется лишь создать (возможно, пустой) инициализационный файл для каждого пакета или субпакета.
3.5. Объектно-ориентированное программированиеВ Python реализована полноценная поддержка ООП. В листинге 3.4 показана заго-товка простого модуля для графического редактора. Листинг всего лишь дает пред-ставление о возможностях Python для читателей, уже знакомых с ООП. Выноски поясняют связь синтаксиса и семантики Python со стандартными возможностями, присутствующими в других языках.
Листинг 3.4. Файл sh.py
"""Модуль sh. Содержит классы Shape, Square и Circle""" class Shape:
"""Класс Shape: содержит метод move"""
def __init__(self, x, y):
self.y = self.y + deltaY
class Square(Shape):
"""Класс Square: наследует от Shape"""
def __init__(self, side=1, x=0, y=0):
Shape.__init__(self, x, y)
self.side = side
class Circle(Shape):
"""Класс Circle: наследует от Shape и содержит метод area""" pi = 3.14159
def __init__(self, r=1, x=0, y=0):
Читать дальше