Создание собственных функций в Python

Обновлено:

1. Ключевое слово def

Для создания собственной функции используется ключевое слово:

def

Правильно:

def

Ключевое слово def сообщает Python:

Сейчас мы определяем новую функцию.

Простейшая функция записывается так:

def my_function():
    pass

Пока эта функция не выполняет никаких полезных действий.


2. Из каких частей состоит определение функции

Рассмотрим:

def my_function():
    pass

Здесь находятся:

def              — ключевое слово
my_function      — имя функции
()               — круглые скобки
:                — двоеточие
pass             — тело функции

Каждая часть имеет своё назначение.


3. Пробел после def

После ключевого слова def ставится пробел:

def my_function():
    pass

Неправильно:

defmy_function():
    pass

В таком варианте Python не увидит отдельное ключевое слово def.


4. Имя функции

После def указывается имя функции:

def show_message():
    pass

Для имён функций действуют почти те же правила, что и для имён переменных.

Имя функции:

  • пишется на английском языке;
  • не начинается с цифры;
  • не содержит пробелов;
  • не содержит восклицательных знаков и других неподходящих символов;
  • не совпадает с ключевым словом Python;
  • должно отражать назначение функции.

5. Стиль snake_case

Имена функций записываются в стиле:

snake_case

Если имя состоит из нескольких слов, они разделяются нижним подчёркиванием.

Хорошие примеры:

def show_message():
    pass
def calculate_total():
    pass
def get_user_name():
    pass
def print_order_status():
    pass

6. Понятное имя функции

Имя должно объяснять, что делает функция.

Плохой вариант:

def f():
    pass

По имени f невозможно понять назначение функции.

Лучше:

def show_greeting():
    pass

Или:

def calculate_order_total():
    pass

Название функции обычно описывает действие, поэтому часто начинается с глагола:

show
calculate
get
create
print
convert

7. Круглые скобки

Сразу после имени функции ставятся круглые скобки:

def show_message():
    pass

Между именем и скобками пробел не ставится.

Правильно:

show_message()

Неправильно:

show_message ()

В будущем внутри этих скобок будут указываться параметры функции.

Сейчас мы создаём простые функции без параметров, поэтому скобки остаются пустыми:

()

8. Двоеточие

После круглых скобок обязательно ставится двоеточие:

def show_message():
    pass

Двоеточие означает, что дальше начинается тело функции.

Неправильно:

def show_message()
    pass

Из-за отсутствия двоеточия программа завершится с ошибкой:

SyntaxError

9. Тело функции

После двоеточия нажимаем Enter и переходим на следующую строку:

def show_message():
    pass

Строка:

pass

находится внутри тела функции.

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


10. Отступ в четыре пробела

Тело функции обязательно записывается с отступом.

По правилам PEP 8 используется четыре пробела:

def show_message():
    pass

Имя функции находится на основном уровне файла, у левой границы:

def show_message():

Тело функции сдвинуто вправо на четыре пробела:

    pass

11. Отступ является частью синтаксиса

В Python отступы имеют значение.

Неправильно:

def show_message():
pass

Строка pass должна находиться внутри функции, но у неё нет отступа.

При запуске файла появится ошибка:

IndentationError

IndentationError сообщает о неправильном отступе.


12. Вложенные блоки

В будущем внутри функций могут находиться другие блоки:

  • условные конструкции;
  • циклы;
  • другие конструкции с двоеточием.

Каждый новый вложенный блок добавляет ещё четыре пробела.

Условный пример:

основной уровень файла
    тело функции
        вложенный блок

Подробно вложенные конструкции мы изучим позже.

Сейчас всё тело функции имеет один отступ в четыре пробела.


13. Ключевое слово pass

Ключевое слово:

pass

является заглушкой.

Оно сообщает Python:

Здесь пока не нужно выполнять никаких действий, но блок существует.

Пример:

def show_message():
    pass

Функция синтаксически правильная, хотя её тело пока пустое по смыслу.


14. Зачем нужен pass

Python не разрешает оставлять тело функции полностью пустым.

Неправильно:

def show_message():

После двоеточия Python ожидает хотя бы одну команду с отступом.

Если функция ещё не написана, используем:

def show_message():
    pass

Позже pass можно удалить и заменить настоящим кодом.


15. Ошибка при пустом теле функции

В файле Visual Studio Code такой код:

def show_message():

не является законченной программой.

При запуске появится ошибка:

IndentationError

Python ожидает блок с отступом после определения функции.

Правильный временный вариант:

def show_message():
    pass

16. Определение функции в IDLE

В IDLE можно написать:

def show_message():
    pass

После тела функции в интерактивной оболочке нужно завершить определение пустой строкой.

Функция будет создана.

При этом её тело ещё не выполняется.

Python только создаёт объект функции и связывает его с именем:

show_message ─────> объект функции

17. Функция является объектом

Собственная функция — это полноценный объект Python.

После определения:

def show_message():
    pass

можно обратиться к имени без круглых скобок:

show_message

В IDLE появится техническое представление объекта:

<function show_message at 0x...>

Например:

<function show_message at 0x10482f420>

Конкретное число будет отличаться.


18. Техническое представление функции

Рассмотрим:

<function show_message at 0x10482f420>

Здесь:

function

сообщает, что перед нами объект функции.

show_message

— имя функции.

0x10482f420

— технический идентификатор в шестнадцатеричной записи.

В CPython он связан с адресом объекта функции в оперативной памяти.

Запоминать это число не нужно.


19. Связь с функцией id()

Можно сравнить:

def show_message():
    pass


print(id(show_message))

Функция id() вернёт идентификатор в десятичной системе счисления.

Для шестнадцатеричного представления того же числа можно использовать:

hex(id(show_message))

Функцию hex() мы пока подробно не изучаем.

Этот пример нужен только для понимания технического отображения:

<function show_message at 0x...>

20. Обращение и вызов — разные действия

Обращение к объекту функции:

show_message

не запускает её.

Мы получаем сам объект функции.

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

show_message()

запускает код, находящийся в её теле.

Круглые скобки после имени означают:

Вызвать функцию.


21. Вызов пустой функции

Создадим функцию:

def show_message():
    pass

Вызовем её:

show_message()

В терминале ничего не появится.

Причина:

  • внутри функции нет print();
  • внутри функции нет полезного действия;
  • pass ничего не делает.

Но функция была успешно вызвана и завершила работу.


22. Что возвращает пустая функция

Функция без явного возвращаемого значения возвращает:

None

Проверим:

def empty_function():
    pass


result = empty_function()

print(result)

Результат:

None

pass не возвращает None самостоятельно.

Функция дошла до конца тела, не встретила return с результатом и поэтому автоматически вернула None.


23. Полный первый пример

def empty_function():
    pass


empty_function()

print(empty_function)


result = empty_function()

print('result:', result)

Программа:

  1. определяет функцию;
  2. вызывает её;
  3. выводит техническое представление объекта функции;
  4. ещё раз вызывает функцию;
  5. сохраняет возвращённый None;
  6. выводит результат.

Пример результата:

<function empty_function at 0x...>
result: None

Первый вызов:

empty_function()

ничего не напечатал.


24. Выражение внутри функции

Заменим pass математическим выражением:

def calculate_number():
    10 + 5

Вызовем функцию:

result = calculate_number()

print(result)

Результат:

None

Python вычислил:

10 + 5

Но результат не был ни сохранён, ни возвращён.

После этого функция дошла до конца и вернула None.


25. Вычисление не означает возврат

Рассмотрим:

def calculate_number():
    10 + 5

Внутри функции получился результат:

15

Но функция не передала этот объект наружу.

Поэтому:

result = calculate_number()

не запишет в result число 15.

В переменной окажется:

None

26. Переменные внутри функции

Создадим переменные внутри функции:

def calculate_number():
    first_number = 10
    second_number = 5
    first_number + second_number

Вызовем:

result = calculate_number()

print(result)

Результат:

None

Даже если вычисления выполнялись, функция ничего явно не вернула.


27. Ключевое слово return

Чтобы вернуть результат из функции, используется ключевое слово:

return

Пример:

def get_greeting():
    return 'Hello'

Теперь функция возвращает строку:

get_greeting()

Результат вызова:

'Hello'

28. Назначение return

Ключевое слово return:

  • завершает работу функции;
  • возвращает указанный результат в место вызова.

Пример:

def get_greeting():
    return 'Hello'

Упрощённо:

get_greeting() ─────> 'Hello'

29. Сохранение возвращённого результата

def get_greeting():
    return 'Hello'


result = get_greeting()

print(result)

Результат:

Hello

Порядок работы:

  1. вызывается get_greeting();
  2. функция возвращает строку 'Hello';
  3. имя result связывается с этой строкой;
  4. print() выводит строку.

30. Статичное возвращаемое значение

Функция:

def get_greeting():
    return 'Hello'

не получает никаких данных извне.

Поэтому при каждом вызове она возвращает одно и то же значение:

print(get_greeting())
print(get_greeting())
print(get_greeting())

Результат:

Hello
Hello
Hello

Пока такая функция полностью статична.

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


31. Большое тело функции

Тело функции может состоять из нескольких строк:

def calculate_total():
    first_number = 10
    second_number = 5
    result = first_number + second_number
    return result

Вызов:

total = calculate_total()

print(total)

Результат:

15

32. Как работает calculate_total()

def calculate_total():
    first_number = 10
    second_number = 5
    result = first_number + second_number
    return result

При вызове функция:

  1. создаёт first_number;
  2. создаёт second_number;
  3. складывает числа;
  4. сохраняет сумму в result;
  5. возвращает значение result.

Упрощённо:

calculate_total() ─────> 15

33. Выражение после return

В return можно написать выражение:

def calculate_total():
    first_number = 10
    second_number = 5
    return first_number + second_number

Функция сначала вычислит:

first_number + second_number

После этого вернёт результат:

15

Оба варианта правильные.


34. Два варианта возврата результата

Первый вариант:

def calculate_total():
    first_number = 10
    second_number = 5
    result = first_number + second_number
    return result

Второй вариант:

def calculate_total():
    first_number = 10
    second_number = 5
    return first_number + second_number

Первый вариант удобен, если промежуточному результату нужно понятное имя или он будет использоваться ещё раз.

Второй вариант короче.


35. В return можно выполнять изученные действия

Например, сложение:

def calculate_sum():
    return 10 + 5

Вычитание:

def calculate_difference():
    return 10 - 5

Возведение в степень:

def calculate_square():
    return 5 ** 2

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

def calculate_total():
    numbers = [10, 20, 30]
    return sum(numbers)

36. Возврат результата другой функции

def get_maximum_number():
    numbers = [10, 25, 5]
    return max(numbers)

Вызов:

result = get_maximum_number()

print(result)

Результат:

25

Сначала срабатывает:

max(numbers)

Затем найденное число возвращается с помощью return.


37. Функция создаёт локальную область видимости

У каждой функции есть собственная локальная область видимости.

Имена, созданные внутри функции, являются локальными:

def calculate_total():
    first_number = 10
    second_number = 5
    result = first_number + second_number
    return result

Локальные имена:

first_number
second_number
result

существуют внутри вызова этой функции.


38. Три изученные области видимости

Теперь мы знакомы с тремя областями видимости.

Встроенная область

В ней находятся заранее доступные имена:

print
len
sum
int
float
list

Глобальная область

В ней находятся имена, созданные на основном уровне файла:

message = 'Hello'


def show_message():
    pass

Глобальные имена:

message
show_message

Локальная область

Создаётся во время вызова функции:

def calculate_total():
    first_number = 10
    second_number = 5

Локальные имена:

first_number
second_number

39. Имя функции находится в глобальной области

Рассмотрим:

def show_message():
    pass

Если функция определена у левой границы файла, имя:

show_message

находится в глобальной области видимости.

Объект функции существует в памяти, а глобальное имя ссылается на него:

show_message ─────> объект функции

40. Пустая локальная область

Создадим глобальную переменную и функцию:

user_message = 'I like music'


def show_local_names():
    print('local:', dir())

Вызовем функцию:

show_local_names()

В простом варианте локальная область не содержит созданных нами переменных:

local: []

Точный результат dir() может зависеть от среды, но собственных локальных имён здесь нет.


41. Глобальная область после создания функции

user_message = 'I like music'


def show_local_names():
    print('local:', dir())


show_local_names()

print('global:', dir())

В глобальной области среди служебных имён будут находиться:

show_local_names
user_message

Функция dir() возвращает и служебные имена Python, но в учебном объяснении мы можем временно их не учитывать.


42. Локальные переменные функции

Добавим переменные внутрь функции:

user_message = 'I like music'


def show_local_names():
    first_name = 'John'
    age = 25
    print('local:', dir())


show_local_names()

Теперь среди локальных имён будут:

age
first_name

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


43. Локальные имена не становятся глобальными

def create_user_data():
    first_name = 'John'
    age = 25

После вызова:

create_user_data()

имена:

first_name
age

не появляются в глобальной области видимости.

Попытка обратиться к ним снаружи:

print(first_name)

приведёт к ошибке:

NameError

44. Локальная область создаётся при вызове

Когда Python встречает:

def create_user_data():
    first_name = 'John'
    age = 25

тело функции пока не выполняется.

Локальные переменные создадутся только при вызове:

create_user_data()

После завершения вызова обычные локальные имена функции исчезают.


45. У каждой функции своя локальная область

def create_first_data():
    first_number = 10
    second_number = 20


def create_second_data():
    price = 99.5
    message = 'Hello'

У первой функции есть свои локальные имена:

first_number
second_number

У второй функции — свои:

price
message

Это разные локальные области видимости.


46. Локальные области функций не объединяются

Первая функция не может напрямую использовать локальную переменную второй функции.

Например:

def create_number():
    number = 10


def print_number():
    print(number)

Вызов:

print_number()

приведёт к ошибке:

NameError

Переменная number является локальной для другой функции.


47. Одинаковые имена в разных областях

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

message = 'Global message'


def show_message():
    message = 'Local message'
    print('local:', message)

Вызовем функцию:

show_message()

Результат:

local: Local message

Внутри функции используется локальная переменная.


48. Глобальная переменная не изменилась

Полный пример:

message = 'Global message'


def show_message():
    message = 'Local message'
    print('local:', message)


show_message()

print('global:', message)

Результат:

local: Local message
global: Global message

Локальная и глобальная переменные являются разными именами из разных областей видимости.


49. Как Python ищет имя

Когда Python встречает имя внутри функции, сначала он ищет его в локальной области.

Поэтому здесь:

message = 'Global message'


def show_message():
    message = 'Local message'
    print(message)

используется локальное значение:

Local message

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


50. Одинаковые имена лучше не использовать без причины

Python умеет различать:

  • локальное имя;
  • глобальное имя.

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

Поэтому лучше использовать их только тогда, когда это действительно понятно и оправданно.

На начальном этапе полезнее выбирать разные и понятные имена.


51. print() внутри функции

Функция может не возвращать значение, а выполнять вывод:

def show_greeting():
    print('Hello')
    print('Welcome to Python')

Вызов:

show_greeting()

Результат:

Hello
Welcome to Python

Функция выполнила два вызова print().


52. Печать не является возвратом

Сохраним результат:

def show_greeting():
    print('Hello')
    print('Welcome to Python')


result = show_greeting()

print('result:', result)

Результат:

Hello
Welcome to Python
result: None

Функция напечатала две строки, но не встретила return.

Поэтому она вернула None.


53. Функция, которая только возвращает

def get_order_count():
    return 1

Вызов:

result = get_order_count()

Функция ничего самостоятельно не выводит.

Она возвращает число:

1

Чтобы увидеть результат в файле, можно написать:

print(result)

54. Функция, которая только печатает

def show_order_count():
    print(2)

При вызове:

result = show_order_count()

функция выведет:

2

Но в result окажется:

None

55. Функция, которая печатает и возвращает

def show_and_get_order_count():
    print(3)
    return 3

Эта функция выполняет два разных действия:

  1. печатает число 3;
  2. возвращает число 3.

56. Сравнение трёх функций

def get_first_value():
    return 1


def show_second_value():
    print(2)


def show_and_get_third_value():
    print(3)
    return 3

Первая функция только возвращает.

Вторая только печатает и неявно возвращает None.

Третья печатает и возвращает.


57. Вызов первой функции внутри print()

print(get_first_value())

Сначала функция возвращает:

1

Затем внешний print() выводит это число:

1

58. Вызов второй функции внутри print()

print(show_second_value())

Сначала внутри функции выполняется:

print(2)

В терминале появляется:

2

После этого функция возвращает None.

Внешний print() печатает этот результат:

None

Итоговый вывод:

2
None

59. Вызов третьей функции внутри print()

print(show_and_get_third_value())

Сначала функция печатает:

3

После этого возвращает число 3.

Внешний print() печатает возвращённое число:

3

Итог:

3
3

Одинаковые значения появились по разным причинам:

  • первое число напечатано внутри функции;
  • второе напечатано внешней функцией print().

60. Полный пример print() и return

def get_first_value():
    return 1


def show_second_value():
    print(2)


def show_and_get_third_value():
    print(3)
    return 3


print(get_first_value())

print(show_second_value())

print(show_and_get_third_value())

Результат:

1
2
None
3
3

61. Определение функции не выполняет её тело

Рассмотрим:

print('Начало программы')


def show_status():
    print('Функция работает')


print('Функция определена')

Результат:

Начало программы
Функция определена

Строка:

Функция работает

не появилась.

Мы только определили функцию, но не вызвали её.


62. Когда выполняется тело функции

Добавим вызов:

print('Начало программы')


def show_status():
    print('Функция работает')


print('Функция определена')

show_status()

print('Конец программы')

Результат:

Начало программы
Функция определена
Функция работает
Конец программы

Тело функции выполнилось только после:

show_status()

63. Код выполняется сверху вниз

Python начинает выполнять файл с первой строки.

Когда он встречает определение функции:

def show_status():
    print('Функция работает')

Python создаёт объект функции, но не запускает её тело.

После этого выполнение продолжается ниже.

Когда Python встречает вызов:

show_status()

он переходит к выполнению тела функции.


64. return завершает функцию

Рассмотрим:

def get_status():
    print('Функция начала работу')
    return 'Готово'
    print('Эта строка не выполнится')

После выполнения:

return 'Готово'

функция немедленно завершает работу.

Поэтому строка:

print('Эта строка не выполнится')

никогда не сработает.


65. Код после return

Код, расположенный в том же блоке после безусловного return, является недостижимым:

def get_status():
    return 'Готово'
    print('Не выполнится')

Как только Python выполняет return, он:

  1. получает возвращаемое значение;
  2. завершает текущий вызов функции;
  3. возвращается в место вызова.

66. Порядок выполнения программы

print('1. Начало программы')


def get_status():
    print('3. Функция начала работу')
    return '4. Готово'
    print('Эта строка не выполнится')


print('2. Функция определена')

result = get_status()

print('5. Функция завершена')
print(result)

Результат:

1. Начало программы
2. Функция определена
3. Функция начала работу
5. Функция завершена
4. Готово

Строка '4. Готово' была возвращена раньше, но распечатали мы её только в самом конце.


67. Почему возвращённая строка появилась последней

Во время вызова:

result = get_status()

функция вернула:

'4. Готово'

Строка была сохранена в переменную result, но ещё не напечатана.

Сначала выполнилось:

print('5. Функция завершена')

И только потом:

print(result)

вывело возвращённую строку.

Возврат и вывод — разные действия.


68. Разбор примера с числами

print(1)


def calculate_result():
    print(1.0)
    return 2.0
    print(3.0)


print(2)

result = calculate_result()

print(3)

print(result)

Результат:

1
2
1.0
3
2.0

69. Пошаговое выполнение

Сначала:

print(1)

выводит:

1

Затем Python определяет функцию:

def calculate_result():

Её тело пока не выполняется.

После этого:

print(2)

выводит:

2

70. Переход внутрь функции

Строка:

result = calculate_result()

вызывает функцию.

Python переходит внутрь:

print(1.0)

Выводится:

1.0

Затем выполняется:

return 2.0

Функция завершается, а число 2.0 сохраняется в result.


71. Почему print(3.0) не сработал

Строка:

print(3.0)

расположена после return:

return 2.0
print(3.0)

До неё выполнение не дойдёт.

return уже завершил функцию.


72. Возвращение в глобальную область

После завершения функции Python возвращается к месту её вызова:

result = calculate_result()

Затем продолжает выполнять глобальный код:

print(3)

Результат:

3

После этого:

print(result)

выводит:

2.0

73. Оформление функций по PEP 8

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

def get_greeting():
    return 'Hello'


result = get_greeting()

print(result)

Между двумя функциями также оставляют две пустые строки:

def get_first_value():
    return 1


def get_second_value():
    return 2

Это улучшает читаемость файла.


74. Основные ошибки

Неправильное ключевое слово

Неправильно:

dev my_function():
    pass

Правильно:

def my_function():
    pass

Нет двоеточия

Неправильно:

def my_function()
    pass

Нет отступа

Неправильно:

def my_function():
pass

Полностью пустое тело

Неправильно:

def my_function():

Временное решение:

def my_function():
    pass

75. Обращение вместо вызова

print(my_function)

выводит техническое представление объекта функции.

my_function()

вызывает функцию.

Круглые скобки имеют принципиальное значение.


76. Вычисление без return

def calculate_total():
    10 + 20

Функция вычислит выражение, но вернёт:

None

Чтобы вернуть сумму:

def calculate_total():
    return 10 + 20

77. Печать вместо возврата

def calculate_total():
    print(10 + 20)

Функция напечатает:

30

Но вернёт:

None

Правильный выбор зависит от задачи:

  • print() — показать данные;
  • return — передать результат для дальнейшего использования.

78. Что изучено на этом уроке

Мы научились:

  • определять функцию с помощью def;
  • выбирать имя функции;
  • писать пустые круглые скобки;
  • ставить двоеточие;
  • создавать тело с отступом;
  • использовать pass;
  • обращаться к объекту функции;
  • вызывать функцию;
  • понимать неявный возврат None;
  • возвращать значение через return;
  • создавать локальные переменные;
  • отличать локальную область от глобальной;
  • различать print() и return;
  • понимать порядок выполнения программы.

79. Что пока не изучаем

На этом уроке мы не рассматриваем:

  • параметры функции;
  • передачу аргументов;
  • именованные аргументы;
  • значения по умолчанию;
  • произвольное количество аргументов;
  • аннотации типов;
  • декораторы;
  • рекурсию;
  • вложенные функции.

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


80. Основные правила урока

Простейшая функция:

def my_function():
    pass

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

my_function()

Функция без явного return возвращает:

None

Функция с результатом:

def get_greeting():
    return 'Hello'

Сохранение результата:

result = get_greeting()

Локальная переменная:

def calculate_total():
    first_number = 10
    second_number = 5
    return first_number + second_number

print() выводит данные:

def show_result():
    print(15)

Но такая функция возвращает:

None

return возвращает результат:

def get_result():
    return 15

После выполнения return функция немедленно завершается.

Код внутри функции выполняется только после её вызова.