# Функции и модули

## Функции

help() - вызов документации для функии

[Встроенные функции RU](https://pythoner.name/documentation/library/functions)

Собственные функции

```
def func_name(var): # объявление функции, название, параметр(ы)
  return var * 2    # возвращение резуьтата функции

>>> func_name(4)    # вызов функции с аргументом
8                   # результат вычислений
```

В python имени функции можно присвоить другое имя (изменить адрес на объект)

```
def sum(x,y):
    return x + y
n = sum
print(n(2,3))
```

Параметры фукнкций могут принримать значения по умолчанию

```
def sum(x,y=4):
    return x + y
a = sum(2)
b = sum(2, 5)
```

Так же можно передавать значения конкретным параметрам

```
def sum(a, b=3, c=7):
    return a + b + c

print(sum(2,4))
print(sum(2,c = 4))
print(sum(b=1,c=4)) # ошибка
```

Имя функции можно передать в качестве аргумента другой функции, т.к. это тоже переменная

```
def sum(x,y):
    return x + y

def func(f, a, b):
    return f(a, b)

n = func(sum, 10, 3)
print(n)
```

### Области видимости переменных

Если значение переменной присвоено внутри функции, то она локальная и её видно только внутри фукнции, в другом случае перменная глобальная и её видно во всей программе.

```
x = 1 # глобальная переменная
y = 3 # глобальная переменная
def func():
    print(x)
    y = 5  # локальная переменная
    print(y)
func()
print(y)
```

```
1
5
3
```

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

```
x = 2  # глобальная переменная
def func():
    global x # указываем, что x глобальная переменная
    print(x)
    x = 1 # переопределяем глобальную переменную
    print(x)
func()
print(x)
```

```
2
1
1
```

### Подробнее

int() - возвращает целое число в десятичной системе счисления

```
int(2.3)
2
```

float(x) - возвращает число с плавающей точкой, созданное из числа или строки x

```
float(3)
3.0
```

Абсолютное число для объекта

```
>>> abs(-2)
2
```

```
>>> a = abs(-3) + abs(-2)
5
```

Возврат значения x в степени y

```
pow(x, y)
```

Округление числа с плавающей точкой

```
round(2,4221) # по умолчанию до 0 цифр после запятой
2
```

```
round(2,4221, 2) # указываем число знаков после запятой
2.42
```

В качеcтве аргументов для функции можно передавать результат вызовы других функий

```
float(round(pow(round(2.4323, 2), 2)))
6
```

## Модули

В Python есть три основных типа модулей: модули, написанные вами, модули, взятые из внешних источников, и предустановленные модули Python. Последний тип также называется стандартной библиотекой. В ней содержится много полезных модулей. Вот лишь некоторые из наиболее полезных модулей со стандартной библиотеки: string, re, datetime, math, random, os, multiprocessing, subprocess, socket, em, json, doctest, unittest, pdb, argparse и sys.

Некоторые модули стандартной библиотеки написаны на Python, а некоторые на C. Большинство из них совместимы со всеми платформами, а некоторые только с Windows и Unix.

Многие из модулей Python, написанные сторонними разработчиками, хранятся в каталоге пакетов Python (Python Package Index, или PyPI). Легче всего их устанавливать с помощью специальной программы pip. Программа поставляется предустановленной в последних дистрибутивах Python. Если у вас этой программы нет, ее можно легко установить. С этой программой установка библиотек PyPI не составит труда. Найдите имя нужной библиотеки, откройте интерфейс передачи команд (командная строка в Windows) и введите pip install library\_name. После этого, импортируйте библиотеку и задействуйте ее в своем коде. Использование программы pip - стандартный способ установки библиотек для большинства операционных систем, но в некоторых библиотеках уже есть готовые двоичные файлы для Windows. Это обычные исполняемые файлы для установки библиотек с помощью графического интерфейса - так, как вы устанавливаете другие программы.

Импорт модуля

```
import math
```

Обращение к функции модуля

```
math.sqrt(16)
```

Документация

```
help(math) # всего модуля
help(math.sqrt) № отельной функции
```

В момент импортирования модуля math создается переменная с именем math

```
>>> type(math)
<class 'module'>
```

Функция type() показала, что тип данных переменной math – модуль. Переменная math содержит ссылку (адрес) модульного объекта. В этом объекте содержатся ссылки на функции (функциональные объекты)

Функция type() показала, что тип данных переменной math – модуль. Переменная math содержит ссылку (адрес) модульного объекта. В этом объекте содержатся ссылки на функции (функциональные объекты)

В Python можно импортировать отдельную функцию из модуля

```
>>> from math import sqrt
>>> sqrt(9)
3.0
```

Таким образом, Python не будет создавать переменную math, а загрузит в память только функцию sqrt(). Теперь вызов функции можно производить, не обращаясь к имени модуля math

При импортировании одноименной функции (from math import sqrt), она заменит функцию из нашего кода. Если импортировать весь модуль (import math), то такой проблемы не будет.

Некоторые модули импортируются автоматически в момент начала работы, например **builtins**

Места хранения модулей по умолчанию

```
import sys
sys.path
```

В целях экономии ресурсов, повторное импортирование не приводит к выполнению модуля, т.е. он повторно не импортируется.

Чтобы импортировать повторно:

```
>>> import imp
>>> imp.reload(modulname)
```

Чтобы отделить исполнение модуля от ипортировния используется специальная переменная **name** (по два нижних подчеркивания). Если мы запускаем модуль, то содержимое переменной **name** будет равно строке **name**, а в случае импортирования – переменная **name** будет содержать имя модуля

```
def sum(a,b):
    return a+b

if __name__ == "__name__": # выполниться только при выполнении модуля
    a = int(input("Введите число: "))
    b = int(input("Введите ещё одно число: "))
    print(sum(a,b))
```

## Тестирование

### Автоматизированное тестирование функций

Если рузультат вызова функции совпадает с описанием, то на экране ничего не появится

```
def func(a,b):
    """
    >>> func(2,4)
    6             # ожидаемый рузултат
    """
    return a+b

import doctest
doctest.testmod()
```
