Объявление функций

Как и в большинстве языков структурного программирования, блоки операторов можно оформлять в виде функций для дальнейшего использования.

Синтаксис:

def 〖имя функции〗(〖аргументы〗):
␣␣␣␣〖операторы〗
␣␣␣␣return 〖возвращаемое значение〗

Функция может возвращать одно или несколько значений (в виде кортежа) или None.

Объявление функции следует рассматривать, как присвоение значения соответствующей переменной.

Функции и модификация аргументов

Базовые типы данных при вызове функций копируются, а составные нет.

def foo(x):
    x = x + 1
    return x
    
w = foo(5) # w == 6
w = 1
r = foo(w) # w == 1, r == 2
def foo(x):
    x[0] = "42"

w = [1, 2, 3]
foo(w) # w == ['42', 2, 3]

Присвоение значений аргументам функции в ее теле равносильно созданию новых переменных.

Функции и область видимости

Функция видит переменные объявленные вне ее тела, но при попытке присвоения создает новые, локальные:

y = 1

def foo(x):
    y = x + y
    return x,y

a,b = foo(1) # y == 1

def foo(x):
    global y # Явно используем y из глобальной области
    x = x + y 
    y = y + 1
    return x,y

a,b = foo(1) # a == 2, b == 2, y == 2

Аргументы по умолчанию (default arguments)

При вызове функций можно пропускать аргументы, если для них задано значение по умолчанию:

def foo(x = 42):
    return x*2
    
w = foo(1) # w == 2
w = foo() # w == 84

Обязательные аргументы всегда должны идти перед аргументами со значениями по умолчанию при объявлении функции:

def foo(x, y, z = 42): #Верно
    return x*y*2

def foo(x = 42, y, z): #Ошибка
    return x*y*2

Порядок аргументов

Обязательные аргументы должны передаваться по порядку.

Аргументы со значениями по умолчанию можно передавать в произвольном порядке:

def foo(a, x = 1, y = 2, z = 3):
    return (x*y*z)/a

w = foo(1, z = 7, y = 7) # Верно w == 49

Функция как аргумент

def foo(x):
    return x**2

def bar(x):
    return x**3 / 3

def calc(f, x, a):
    return f(x) + a
    
w = calc(foo,1,2) # w == 3
w = calc(bar,3,2) # w == 11.0

Что еще нужно знать о функциях

  • Функция — объект специального составного типа function
  • Объявление одной и той-же функции несколько раз не выдаст ошибки
  • Функции можно складывать в списки, словари, проверять на тождество
  • Функции можно объявлять внутри функций, кроме слова global есть слово nonlocal, которое делает тоже самое, но для локальных переменных
  • Функции с помощью специальных приемов могут обрабатывать произвольное число аргументов (подробнее)
  • Функции можно вызывать рекурсивно
  • Есть особые функции: лямбда (безымянные) и генераторы (запоминающие свое состояние)

Исключения (exception)

Возникновение исключений

Когда происходит ошибка — возбуждается соответствующее исключение. Обработка исключения — основой способ обработки ошибок в Python.

4/0
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

Когда происходит исключение Python начинает искать обработчик исключения для данного блока, при необходимости выходя из функций. Если обработчик не найден, то интерпретатор завершается (или выдает ошибку в интерактивном режиме).

Обработка исключений

try:
    #блок кода в котором
    #ожидается возникновение исключения
except ZeroDivisionError as e:
    #блок кода который будет выполнен
    #если возникнет исключение типа ZeroDivisionError
else:    
    #блок кода который будет выполнен
    #если исключение в блоке try не возникнет
finally:
    #блок кода, который будет выполнен в любом случае

Можно перехватывать все типы исключения написав except:, но это маскирует ошибки.

Популярные типы исключений

Исключение Описание
IndexError Индекс за пределами массива
KeyError Ключ отсутствует в словаре
NameError Обращение к необъявленной переменной (методу, классу)
UnboundLocalError Обращение к недоступной переменной
OSError Ошибки системы (права на файл, нет места на диске, …)
TypeError Операция не поддерживается данным типом данных (вычитание строк, …)
ValueError Недопустимое значение переменной (float('hello'), …)
NotImplementedError Метод не реализован

Исключение также можно выбросить прямо в коде. Для этого используется ключевое слово raise, например:

raise Exception("Произошла ошибка")

Примеры использования

value_str = "123.15"
value_float = 0.0

try:
    value_float = float(value_str)
except ValueError:
    print("Это не число!")
finally:
    print(value_float)
    
print(value_float*10)

Примеры использования в функции

def fix(x, fix_type = None):
    if fix_type == "round":
        return round(x)
    elif fix_type == "ceil":
        return math.ceil(x)
    elif fix_type == "trunc":
        return math.trunc(x)
    else:
        raise ValueError("Недопустимое значение переменной fix_type")

ft = input("Введите тип округления:")
value = 73/13
try:
    value = fix(value, ft)
except ValueError:
    print("Неправильный тип округления")
    value = fix(value, "round")
    

Что еще нужно знать об исключениях

  • «Я не знаю, что дальше делать, я вызываю raise »
  • Оператор try почти ничего не стоит, но обработка возникшего исключения дело более ресурсоемкое (хотя и не очень), поэтому не следует использовать исключения вместо if
  • Объект исключения можно преобразовать в str, обычно это используется для вывод сообщений об ошибках
  • Исключение можно возбудить повторно, вызвав raise без аргументов в обработчике
  • Исключения можно содержательно анализировать с помощью методов модуля traceback

Модули

import modulename

Поиск при импорте:

  • Файлы в папке программы
  • Файлы в переменной $PYTHONPATH
  • Сторонние пакеты
  • Стандартная библиотека

Собственные модули

Файл mylib.py:

def foo(x):
    return x*x

class MyClass:
    def __init__(self):
        self.v = 0

Файл program.py:

import mylib

print(mylib.foo(4))
form mylib import MyClass,foo
ob = MyClass()
print(foo(4))

Разница между импортом и запуском

Модуль может определить загружен ли он через import или запущен как программа:

if __name__ == "__main__":
    main()

Функция main() будет вызвана только если скрипт запущен как программа и не будет запускаться если он импортирован в другой скрипт.

Важные модули стандартной библиотеки

Модули Возможности
sys Служебные функции интерпретатора, аргументы командной строки, выход
os, shutils Операции с файлами и папками, переменные окружения, запуск сторонних программ
glob, Path Операции с путями к файлам
math, statistics Базовые математические функции
random Генерация случайных чисел и последовательностей
struct Работа с бинарными структурами
datetime Работа с датой и временем
copy Копирование составных объектов
pprint Улучшенный print
pickle Сохранение объектов Python в файлы

Важные сторонние модули доступные в pip

Модуль Возможности
numpy Эффективные методы для работы с числовыми данными
scipy Коллекция математических методов
matplotlib Рисование графиков
sympy Символьные вычисления
pandas Таблицы данных
requests Доступ к файлам через HTTP