Функции

Функция — часть программы, реализация которой выполняется отдельно. Обычно часть кода выделяют в функции, если один и тот же кусок кода нужно повторить несколько раз с разными значениями переменных. Примеры встроенных в Python функций: input(), print(), sum(). Можно и нужно писать свои функции.

Функция состоит из:

  • Названия — отражает то, что функция должна делать.
  • Списка аргументов (параметров) — то, с чем это делать.
  • Тела функции — что она делает на самом деле.
  • Результата (возвращаемого значения) — то, что она сделала.

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

def название(параметры): тело функции return результат

Ключевое слово return пишется, если нужен результат вычислений. Если не нужен результат, только побочные эффекты, то можно не писать return.

Пример с побочным эффектом:


In [1]:
def print_sum(a, b):
    print(a + b)

Пример с возвращаемым значением:


In [2]:
def get_sum(a, b):
    return a + b

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

Вызов функции

Параметры при вызове функции можно задавать явно:


In [3]:
print_sum(5, 7)


12

Переменные тоже могут быть параметрами при вызове функции:


In [4]:
a, b = 7, 8
print_sum(a, b)
print_sum(a, 1)


15
8

Если у функции есть возвращаемое значение, то стоит его запомнить в переменную или хотя бы вывести.


In [5]:
print(get_sum(2, 3))

a = get_sum(1, 4)
print(a)

get_sum(1, 2)  # У этой строчки нет эффекта. Результат посчитан, но не запомнен.


5
5
Out[5]:
3

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


In [6]:
a = 15
x = get_sum(1, a)
y = get_sum(x, get_sum(2, 2))
print(x, y)


16 20

Тип возвращаемого значения

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


In [7]:
def is_leap(year):
    return year % 4 == 0 and year % 100 != 0 or year % 400 == 0


print(is_leap(2012))


True

Тип float:


In [8]:
def mean(a, b):
    return (a + b) / 2


print(mean(6, 6))
print(mean(5, 6))


6.0
5.5

В случае функции с побочным эффектом без возвращаемого значения Python всё равно вернёт специальное значение: None, которое означает, что значение отсутствует. Но так писать не надо, нет результата — значит нет, не нужно пытаться его достать.


In [9]:
def print_effect():
    print("Some effect")


result = print_effect()
print(result)

print_effect()  # Правильно так


Some effect
None
Some effect

Виды параметров

Формальные и фактические

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

Фактические параметры — это конкретные значения, которые связываются с формальными параметрами при вызове функции.


In [1]:
def add_to_list(lst, i, delta):  # lst, i, delta - формальные параметры
    lst[i] += delta
    
a = [1, 2, 3]
x = 4
add_to_list(a, 1, x)  # [1, 2, 3], 1, 4 - фактические параметры

По умолчанию

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


In [3]:
def inc(a, b=1): 
    return a + b

print(inc(3, 5))

# b - необязательный параметр
print(inc(3))


8
4

Именованые

Любой параметр можно передать, явно указав имя:


In [7]:
# Эти три вызова функции эквивалентны
print(inc(2, b=5))
print(inc(a=2, b=5))
print(inc(b=5, a=2))


7
7
7

In [11]:
# Параметры sep, end и file у функции print - это именованые параметры со значением по умолчанию
print(1, 2, 3, sep=" | ", end=" !")


1 | 2 | 3 !

In [ ]:
def smth(a, b=2, c=3, d=4): 
    print(a, b, c, d) 
    
# Правильно 
smth(1) 
smth(c=5, a=3) 
smth(3, c=5) 
smth(1, 3, 5) 
 
# Неправильно 
smth()  # пропущен требуемый аргумент 
smth(a=5, 1000)  # позиционный параметр вслед за именованным 
smth(10, a=20)     # повторное значение параметра 
smth(arg=100500)  # неизвестное имя параметра

Произвольное количество


In [14]:
def sum(*args):  # args - это список аргументов функции 
    result = 0 
    for x in args: 
        result += x 
    return result 
 
print(sum(1))  # args = [1]
print(sum(1, 2, 3))  # args = [1, 2, 3]

lst = [1, 2, 4, 8, 16, 32] 
print(sum(*lst))  # args = [1, 2, 4, 8, 16, 32]


1
6
63

Области видимости

Область видимости — это изолированная часть программы со своим набором переменных.

Все переменные, объявленные в основной программе находятся в глобальной области видимости.

При каждом вызове функции создаётся новая локальная область видимости.


In [16]:
# При каждом вызове функции fib создаётся локальная область видимости с переменными n, a, b и i
def fib(n):
    a, b = 0, 1
    for i in range(n):
        a, b = b, a + b
    return a

# Глобальная область видимости содержит переменную k
k = int(input())
print(fib(k))


7
13

In [17]:
# При отсутствии переменной в локальной области видимости, используется такая же переменная из глобальной
def f(a):
    return a + b

b = 4
print(f(7))


11

In [24]:
# Ошибка. Локальная переменная неизвестна после окончания функции 
def f():
    local_var = "Only local"
    print(local_var)

f()
print(local_var)


Only local
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-24-c2e1bbb7f483> in <module>()
      5 
      6 f()
----> 7 print(local_var)

NameError: name 'local_var' is not defined

global

Ключевое слово global говорит не создавать локальную переменную и изменять вместо этого глобальную.


In [19]:
accumulator = 0

def accumulate(x):
    global accumulator
    accumulator += x
    
accumulate(8)
accumulate(13)
print(accumulator)


21

In [22]:
# Ошибка. Попытка использовать глобальную переменную перед созданием локальной
def f():  
    print(s) 
    s = "Local variable" 
    print(s)

s = "Global variable" 
f()


---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-22-121980ba034d> in <module>()
      6 
      7 s = "Global variable"
----> 8 f()

<ipython-input-22-121980ba034d> in f()
      1 # Ошибка. Попытка использовать глобальную переменную перед созданием локальной
      2 def f():
----> 3     print(s)
      4     s = "Local variable"
      5     print(s)

UnboundLocalError: local variable 's' referenced before assignment