Учебная страница курса биоинформатики,
год поступления 2017
Указания к заданию 10
Функции
Собственная функция объявляется ключевым словом def, после которого следует имя функции с перечисленными в скобках аргументами.
В конце функции может следовать ключевое слово return, после которого следует, что возвращает функция.
Если после return ничего нет или оно вообще опущено, то считается, что функция возвращает специальное значение None.
Если после return идет перечисление переменных, то функция возвращает кортеж из них
Также в функции можно задавать параметры по умолчанию, тогда если аргумент будет опущен при вызове, то функция будет использовать его значение по умолчанию.
1 def count(n=5, phrase="Count"):
2 for i in range(n):
3 print phrase
4
5 count(2, "Hi") # Hi\nHi\n
6 count(n=2, phrase="Hi") # Hi\nHi\n
7 count(n=3) # "Count\nCount\nCount\n"
8 count(3) # "Count\nCount\nCount\n"
9 count() # "Count\nCount\nCount\nCount\nCount\n"
10 #count("Count") # так работать не будет, т.к Python посчитает, что вы передали ему n
11 count(phrase="Hi") # Hi\nHi\nHi\nHi\nHi\n
Если вы объявите две функции с одинаковыми именами, то вызываться будет последняя объявленная.
Рекурсия
Рекурсия в программировании (в простейшем варианте) — это вызов в самой функции этой же функции. Python поддерживает рекурсию. При этом стоит помнить, что любой рекурсивный алгоритм может быть переписан в нерекурсивный, что, как правило, делает его более быстрым и безопасным.
Пример — рекурсивная версия функции count.
Собственный модуль
Собственный модуль может представлять собой файл с расширением .py или директорию, содержащую файлы .py и поддиректории (в случае с директорией такой модуль надо оформлять определенным образом; здесь мы не будем рассматривать, как это делать).
Собственный модуль подключается так же, как библиотека. Для этого он должен находиться в одной директории с вашим скриптом. Если нужные вам функции fun1 и fun2 описаны в файле mymodule.py,
то пишете:
или
Если вы не используете прием, который описан дальше, в вашем файле-модуле не должно быть никаких исполняемых конструкций, так как при его импортировании они исполнятся.
К примеру:
При запуске main.py выведется
"Hello, I've been imported" "Main script"
Дополнительная информация
Иногда удобно писать скрипт, который можно использовать и как модуль, и как самостоятельный скрипт. В этом случае надо как-то избежать описанной выше проблемы. Для этого используется конструкция
if __name__ == "__main__":
Примечание (С.А.С.). Думаю, что использовать этот приём начинающим не надо. На мой взгляд, необходимо разделять модули с функциями, которые могут понадобиться в нескольких программах, и файлы с собственно программами (которые могут импортировать "многоразовые" функции или содержать какие-то "одноразовые" функции). В первых не должно быть "main"'а, разве что с печатью справки о содержании модуля, да и то, для такой справки есть более каноническое место.
Обработка ошибок в Python. Exception
Во время выполнения программы может возникнуть непредвиденный случай — "Exception". Если это никак не предусмотрено программистом, то программа, выдав исключение, аварийно завершает работу. Иногда данный сценарий для нас неприемлем: допустим, мы обрабатываем независимые файлы одной программой и время обработки каждого файла достаточно велико. В таком случае мы заинтересованы в том, чтобы программа в случае ошибки (например, отсутствие какого-то файла), не "падала", а продолжала работу с другими файлами, выдав предупреждение пользователю в консоль.
Для данной задачи в Python существует конструкция try .. except
Кроме того, в except можно указывать, что именно мы хотим перехватить — например, у нас возникает ошибка ValueError. Тогда Вместо Exception указываем именно ValueError.
А если хотим обрабатывать ValueError одним способом, а остальные исключения — другим? Тогда можно повторить except несколько раз:
Хорошим стилем в Python считается "ловить то, что ловишь", то есть указывать в except имя именно той ошибки, которую вы хотите обработать, а не просто Exception. К сожалению, для этого надо знать точное имя ошибки, что не всегда удобно.
Часто можно встретить такой стиль написания:
Такой код будет работать, и часто такой код можно писать. Но возникают трудности с возможностью прерывания работы программы, содержащей такую конструкцию (сигнал остановки программы толкуется как ошибка, которую можно обработать), потому так надо писать только тогда, когда уверены, что сойдет с рук. В данном практикуме такой код будет штрафоваться.
Работа с сетью. Модуль urllib2
Пакет urllib2 предназначен для работы с сетью.
Все, что пока вам из него нужно знать — функция urlopen — открывает веб-ресурс как обычный файл. После открытия с ним можно работать как с обычным файлом, открытым на чтение.
Для удобства работы можно прочитать содержимое веб-ресурса, записать его в локальный файл и далее работать уже с последним:
Это позволяет избежать проблем, возникающих при временных неполадках в сети.
Лайфхаки (дополнительная информация)
Склеивание строк. Если ml — список, состоящий только из строк, то выражение "\t".join(ml) возвращает строку из элементов списка, "склееных" табулятором (попробуйте!). Терминология: join есть метод объекта типа "строка", принимающий аргумент типа "список".
Итерация без создания списка. Если вам не нужен сам список, создаваемый range, то можно вместо range использовать в цикле for фукнцию xrange — она расходует значительно меньше памяти и выполняется быстрее. В Python3 range ведет себя как xrange сразу
Больше об ошибках
В языках программирования существует два основных способа обработки ошибок, возникающих в ходе выполнения программы.
Возвращение ошибки
Первый из них — возвращение ошибки функцией, в которой она произошла, что не приводит к остановке программы и позволяет пользователю самому решить, что с этой ошибкой делать.
При этом ошибка может возвращаться функцией как дополнительное значение:
А может вместо самого значения:
Второй способ короче, но может возникнуть ситуация, когда любое значение, которое вернет функция, может быть осмысленным, и тогда возвращать какое-то специфическое значение не получится.
Обратите внимание на сравнение чего-то с None:
только так сравнивать и надо. Испольовать для этого обычное сравнение:
неправильно (дело в том, что == для разных типов в Python может значить разное).
Исключения
Второй способ, который рассматривался в этом практикуме, это обработка исключений — Exception. В разных языках они создаются по-разному, но суть одна — если произошла ошибка, сообщить о ней из самой функции так, чтобы если ничего такой ошибки не ожидает, то программа прекращает свою работу.
Чтобы "ожидать" исключение и используется конструкции типа try… except
Что лучше?
Механизм передачи ошибок функцией, как правило, работает быстрее. Однако он требует бОльшего количества, иногда более запутанного кода.
Механизм исключений, как правило, создает менее запутанный код, но работает медленнее, к тому же, частое использование
полностью нивелирует пользы от exception
В Python принято использовать механизмы исключений ("сначала пробуй, потом извиняйся"), они оптимизированы, насколько это возможно в Python.