Определение функций с def

Функции — это важный инструмент для упрощения и организации кода. Они позволяют выполнять повторяющиеся задачи, инкапсулировать логику и делать код более читаемым. В Python функции определяются с помощью ключевого слова def. В этой лекции мы подробно рассмотрим, как определить функции, какие они могут иметь особенности и приведём множество примеров их использования.

Что такое функция?

Функция — это именованный блок кода, который выполняет определённую задачу. После определения функции её можно вызвать несколько раз в различных частях программы. Это позволяет избежать повторения кода, улучшает его структуру и упрощает тестирование и отладку.

 

Определение функции

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

Общая структура функции:

def имя_функции(аргументы):
    # тело функции


Пример 1: Простая функция без аргументов

Рассмотрим простую функцию, которая выводит сообщение на экран:

def say_hello():
    print("Привет, мир!")

Эта функция не требует аргументов и просто выполняет печать сообщения. Вызов функции осуществляется так:

say_hello()  # Выведет: Привет, мир!


Пример 2: Функция с аргументами

Функции могут принимать аргументы, которые позволяют передавать данные в функцию. Пример функции, принимающей один аргумент:

def greet(name):
    print(f"Привет, {name}!")

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

greet("Мария")  # Выведет: Привет, Мария!


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

Функции могут принимать несколько аргументов. Рассмотрим функцию, которая складывает два числа:

def add(a, b):
    return a + b

Функция возвращает сумму двух чисел:

result = add(5, 7)
print(result)  # Выведет: 12


Пример 4: Возвращаемое значение

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

def multiply(x, y):
    return x * y

Результат функции можно сохранить в переменную и использовать её далее:

product = multiply(4, 6)
print(product)  # Выведет: 24


Пример 5: Множественные возвращаемые значения

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

def get_min_max(numbers):
    return min(numbers), max(numbers)

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

minimum, maximum = get_min_max([2, 8, 1, 10, 4])
print(f"Минимум: {minimum}, Максимум: {maximum}")  # Выведет: Минимум: 1, Максимум: 10


Пример 6: Вложенные функции

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

def outer_function(x):
    def inner_function(y):
        return y * y
    return inner_function(x) + x

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

result = outer_function(3)
print(result)  # Выведет: 12


Пример 7: Функции в качестве аргументов

Функции могут передаваться как аргументы другим функциям. Это полезно для создания гибких и универсальных решений:

def apply_function(func, value):
    return func(value)

def square(x):
    return x * x

result = apply_function(square, 5)
print(result)  # Выведет: 25


Пример 8: Функции как возвращаемое значение

Функция может возвращать другую функцию. Это позволяет создавать функции, которые настраиваются в зависимости от переданных параметров.

def make_multiplier(multiplier):
    def multiplier_function(x):
        return x * multiplier
    return multiplier_function

Использование:

doubler = make_multiplier(2)
tripler = make_multiplier(3)

print(doubler(5))  # Выведет: 10
print(tripler(5))  # Выведет: 15


Пример 9: Функции для обработки данных

Функции часто используются для обработки данных. Рассмотрим функцию, которая фильтрует список чисел, оставляя только чётные:

def filter_even(numbers):
    return [num for num in numbers if num % 2 == 0]

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

numbers = [1, 2, 3, 4, 5, 6]
even_numbers = filter_even(numbers)
print(even_numbers)  # Выведет: [2, 4, 6]


Пример 10: Функции с несколькими операциями

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

def sum_and_square(a, b):
    sum_result = a + b
    return sum_result ** 2

Использование:

result = sum_and_square(3, 4)
print(result)  # Выведет: 49


Пример 11: Функции для работы с коллекциями

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

def average(numbers):
    return sum(numbers) / len(numbers)

Использование функции:

numbers = [10, 20, 30, 40, 50]
avg = average(numbers)
print(avg)  # Выведет: 30.0


Пример 12: Функции для обработки строк

Функции могут использоваться для обработки строк. Например, функция, которая преобразует строку в верхний регистр и возвращает её длину:

def process_string(text):
    upper_text = text.upper()
    return len(upper_text)

Использование функции:

length = process_string("hello world")
print(length)  # Выведет: 11

 

Роль print в отладке

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


Пример 1: Использование print для отладки

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

def calculate_sum(a, b):
    return a + b

result = calculate_sum(5, 7)
print(result)  # Выведет: 12


Пример 2: Функция с выводом данных

Если функция уже выполняет вывод данных, использование print может быть избыточным:

def greet(name):
    print(f"Привет, {name}!")

greet("Анна")  # Выведет: Привет, Анна!

В этом случае функция уже выполняет свою основную задачу — выводит сообщение. Добавление print для отладки не требуется, поскольку функция уже делает то, что должна.


Пример 3: Функция с возвращаемым значением

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

def multiply(a, b):
    return a * b

result = multiply(3, 4)
# Результат можно использовать в дальнейшем, например:
final_result = result + 10
print(final_result)  # Выведет: 22

 

 

Основы аннотаций функций

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

def add(x: int, y: int) -> int:
    return x + y

В этом примере:

  • x: int означает, что аргумент x должен быть типа int.
  • y: int — аргумент y также должен быть типа int.
  • -> int показывает, что функция возвращает значение типа int.


2. Синтаксис аннотаций

Аннотации могут быть любыми выражениями. Чаще всего используются аннотации для указания типов данных, но можно использовать любые объекты: строки, списки, словари, функции, классы и т. д.

Пример с разными типами данных:

def greet(name: str, age: int) -> str:
    return f"Hello, {name}! You are {age} years old."

Здесь:

  • name: str — ожидается строка.
  • age: int — ожидается целое число.
  • -> str — функция возвращает строку.


3. Необязательность аннотаций

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

def multiply(a: int, b: int) -> int:
    return a * b

# Передаём строки вместо чисел
result = multiply("3", "5")  # Работает, вернёт "33333"


4. Использование None и необязательных параметров

Для параметров, которые могут быть необязательными или принимать значение None, также можно указывать аннотации. В таких случаях часто используется тип Optional, который позволяет параметру быть либо указанного типа, либо None.

Пример:

from typing import Optional

def display_info(name: str, age: Optional[int] = None) -> str:
    if age is None:
        return f"{name}, age not provided"
    return f"{name} is {age} years old"

Здесь параметр age может быть как целым числом, так и None, что делает его необязательным.


5. Аннотации сложных типов данных

Python позволяет аннотировать сложные типы данных, такие как списки, словари, множества и т. д. Для этого можно использовать типы из модуля typing: List, Dict, Set, Tuple и другие.

Пример для списка:

from typing import List

def process_numbers(numbers: List[int]) -> int:
    return sum(numbers)

Здесь:

  • numbers: List[int] означает, что параметр numbers должен быть списком целых чисел (int).
  • Функция возвращает целое число (-> int), которое является суммой элементов списка.

Пример для словаря:

from typing import Dict

def count_items(data: Dict[str, int]) -> int:
    return sum(data.values())

Здесь:

  • data: Dict[str, int] — словарь, где ключи — строки, а значения — целые числа.


6. Аннотации с кортежами и другими коллекциями

Для аннотаций кортежей и других структур данных также используется модуль typing. В следующем примере показано, как аннотировать кортеж:

from typing import Tuple

def get_coordinates() -> Tuple[float, float]:
    return (45.0, 90.0)

Здесь:

  • Функция возвращает кортеж из двух элементов типа float.


7. Аннотации функций с переменным числом аргументов

Для функций, принимающих переменное количество аргументов, можно аннотировать как позиционные аргументы *args, так и именованные аргументы **kwargs.

Пример:

from typing import Any

def print_all(*args: Any, **kwargs: Any) -> None:
    for arg in args:
        print(arg)
    for key, value in kwargs.items():
        print(f"{key}: {value}")

Здесь:

  • *args: Any — функция может принимать любое количество аргументов любого типа.
  • **kwargs: Any — функция может принимать любое количество именованных аргументов любого типа.
  • Функция ничего не возвращает, поэтому аннотация возвращаемого значения — None.


8. Инспекция аннотаций

Аннотации хранятся в специальном атрибуте функции __annotations__, который является словарём, где ключи — имена аргументов, а значения — аннотации.

Пример:

def add(x: int, y: int) -> int:
    return x + y

print(add.__annotations__)
# Вывод: {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}

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


9. Аннотации в Python 3.9+ и 3.10+

С выходом Python 3.9 аннотации стали ещё удобнее. Теперь вместо использования типов из typing, таких как List и Dict, можно использовать встроенные типы напрямую.

Пример для Python 3.9+:

def process_numbers(numbers: list[int]) -> int:
    return sum(numbers)

В Python 3.10 появилась поддержка оператора объединения типов |. Это удобная альтернатива Optional:

def display_info(name: str, age: int | None = None) -> str:
    if age is None:
        return f"{name}, age not provided"
    return f"{name} is {age} years old"

Здесь int | None — это то же самое, что и Optional[int].


10. Аннотации и типизация в реальном мире

Несмотря на то что Python остаётся динамически типизированным языком, аннотации играют важную роль в современном программировании. Они помогают:

  • Улучшить читаемость кода и упростить его поддержку.
  • Использовать инструменты статической проверки типов, такие как mypy.
  • Ускорить разработку за счёт автодополнения в IDE.
  • Избежать некоторых типов ошибок благодаря более строгим проверкам типов.

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


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

РазделОписаниеПримеры
Определение функцииФункция определяется с помощью ключевого слова def, имени функции, круглых скобок и двоеточия.def greet(name): ...
Простая функция без аргументовФункция, которая не принимает аргументов и просто выполняет действие.def say_hello(): print("Привет, мир!")
Функция с аргументамиФункция, которая принимает аргументы и использует их в своём теле.def greet(name): print(f"Привет, {name}!")
Функция с несколькими аргументамиФункция, которая принимает несколько аргументов.def add(a, b): return a + b
Возвращаемое значениеФункция может возвращать значение с помощью return.def multiply(x, y): return x * y
Множественные возвращаемые значенияФункция возвращает несколько значений, упакованных в кортеж.def get_min_max(numbers): return min(numbers), max(numbers)
Вложенные функцииФункции могут содержать другие функции внутри, доступные только в рамках внешней функции.def outer_function(x): def inner_function(y): return y * y
Функции в качестве аргументовФункции могут передаваться в другие функции в качестве аргументов.def apply_function(func, value): return func(value)
Функции как возвращаемое значениеФункция может возвращать другую функцию.def make_multiplier(multiplier): def multiplier_function(x): return x * multiplier
Функции для обработки данныхФункции часто используются для обработки и фильтрации данных.def filter_even(numbers): return [num for num in numbers if num % 2 == 0]
Функции с несколькими операциямиФункции могут выполнять несколько операций.def sum_and_square(a, b): sum_result = a + b; return sum_result ** 2
Функции для работы с коллекциямиФункции могут использоваться для работы с коллекциями данных, например, для вычисления среднего значения.def average(numbers): return sum(numbers) / len(numbers)
Функции для обработки строкФункции могут использоваться для обработки строк, например, преобразования в верхний регистр.def process_string(text): upper_text = text.upper(); return len(upper_text)
Роль print в отладкеФункция print используется для отладки, чтобы увидеть результаты или промежуточные значения.def calculate_sum(a, b): return a + b; print(calculate_sum(5, 7))
Документация функцииДокументация добавляется сразу после определения функции и улучшает читаемость кода.def divide(a, b): """ Делит число a на число b. ... """ return a / b

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

 

Функции являются основным инструментом для упрощения и структурирования кода в Python. Они позволяют выполнять повторяющиеся задачи, работать с различными данными и возвращать результаты для дальнейшего использования. Понимание основ определения функций, их аргументов и возвращаемых значений поможет вам создавать более эффективные и читаемые программы. Также важно помнить, что print предназначен в первую очередь для отладки, и использование его в функциях, которые уже возвращают или выводят данные, может быть необязательно.

Перейти к следующему шагу

Комментарии