Определение функции
Функция — это именованный блок кода, который можно вызывать:
def greet():
print("Привет!")
greet() # Вызов функции -> "Привет!"
Параметры и аргументы
Функции могут принимать входные данные:
def greet(name):
print(f"Привет, {name}!")
greet("Анна") # "Привет, Анна!"
greet("Мир") # "Привет, Мир!"
Возврат значения — return
return передаёт результат обратно в вызывающий код:
def add(a, b):
return a + b
result = add(5, 3)
print(result) # 8
# Функция без return возвращает None
def do_nothing():
pass
print(do_nothing()) # None
Параметры по умолчанию
Можно задать значения по умолчанию. Параметры со значениями по умолчанию всегда идут в конце списка — после обычных (обязательных) параметров:
def greet(name, greeting="Привет"):
print(f"{greeting}, {name}!")
greet("Анна") # "Привет, Анна!"
greet("Анна", "Здравствуйте") # "Здравствуйте, Анна!"
Если расположить параметр со значением по умолчанию перед обязательным, Python вызовет ошибку SyntaxError.
Документирование (docstring)
Строка документации сразу после def:
def add(a, b):
"""Возвращает сумму двух чисел."""
return a + b
print(add.__doc__) # "Возвращает сумму двух чисел."
help(add) # Покажет документацию
Несколько параметров
Функция может принимать любое количество параметров через запятую:
def describe_person(name, age, city):
print(f"{name}, {age} лет, город {city}")
describe_person("Олег", 25, "Москва")
# "Олег, 25 лет, город Москва"
# Параметры передаются по порядку
def power(base, exp):
return base ** exp
print(power(2, 10)) # 1024
print(power(10, 2)) # 100 (порядок важен!)
Область видимости переменных
Переменные, созданные внутри функции, не видны снаружи (локальная область видимости):
def my_func():
x = 100 # Локальная переменная
print(x)
my_func() # 100
# print(x) # Ошибка! NameError: x не определена
Глобальные переменные и global
Значение глобальной переменной (созданной вне функции) можно свободно читать внутри функции. Но если присвоить ей новое значение, Python создаст новую локальную переменную с тем же именем — глобальная не изменится:
count = 10
def set_count():
count = 5 # Локальная переменная, не глобальная!
set_count()
print(count) # 10 (глобальная не изменилась)
Чтобы изменить именно глобальную переменную, используйте оператор global внутри функции:
count = 10
def set_count():
global count # Обращаемся к глобальной переменной
count = 5
set_count()
print(count) # 5 (теперь изменилась!)
global указывается в начале функции, до присваивания. Используйте его осторожно: злоупотребление глобальными переменными усложняет отладку. Лучше передавать значения через параметры и возвращать результат через return.
Именованные аргументы
При вызове можно явно указать, какому параметру присваивается значение. Это позволяет не запоминать порядок:
def greet(name, greeting="Привет"):
print(f"{greeting}, {name}!")
# Позиционные аргументы (по порядку)
greet("Анна", "Здравствуйте") # "Здравствуйте, Анна!"
# Именованные аргументы (порядок не важен)
greet(greeting="Здравствуйте", name="Анна") # "Здравствуйте, Анна!"
greet(name="Борис") # "Привет, Борис!"
# Смешанный вызов: сначала позиционные, затем именованные
greet("Виктор", greeting="Добрый день") # "Добрый день, Виктор!"
Аннотации типов
Начиная с Python 3.5 (PEP 484), можно указывать ожидаемые типы параметров и возвращаемого значения, а с Python 3.6 (PEP 526) — аннотации переменных. Это помогает читать код и использовать автодополнение в IDE:
def add(a: int, b: int) -> int:
"""Складывает два целых числа."""
return a + b
def greet(name: str, times: int = 1) -> None:
"""Приветствует указанное количество раз."""
for _ in range(times):
print(f"Привет, {name}!")
result: int = add(5, 3) # Аннотация переменной
greet("Анна", 3) # Аннотации не проверяются во время выполнения
⚠️ Важно: аннотации типов не проверяются интерпретатором. Для проверки используйте инструменты вроде
mypy.def add(a: int, b: int) -> int: return a + b # Интерпретатор не проверяет типы — это просто подсказки print(add(2, 3)) # 5 print(add("a", "b")) # "ab" — хотя ожидались числа, ошибки нет
Практический пример: калькулятор
Объединим изученные концепции в одной программе:
def calculate(a: float, b: float, operation: str = "+") -> float:
"""Выполняет арифметическую операцию над двумя числами.
Аргументы:
a, b — числа
operation — знак операции: "+", "-", "*", "/"
Возвращает:
Результат вычисления.
"""
if operation == "+":
return a + b
elif operation == "-":
return a - b
elif operation == "*":
return a * b
elif operation == "/":
if b != 0:
return a / b
else:
print("Ошибка: деление на ноль!")
return None
else:
print(f"Неизвестная операция: {operation}")
return None
# Использование
print(calculate(10, 5, "+")) # 15 (аннотации не конвертируют типы — 10 + 5 = 15)
print(calculate(10, 5, "/")) # 2.0 (деление всегда возвращает float)
print(calculate(10, 0, "/")) # Ошибка: деление на ноль!
# None