Как функция возвращает результат в Python: полное руководство
Механизм возврата значения из функции
Основной способ - оператор return.
После выполнения return функция завершается и передаёт указанное значение вызывающему коду. Если return не указан, функция возвращает None.
def square(x):
return x * x
result = square(5)
print(result) # 25аргументы print python (аргументы функции print в python)
25
Python 3 аргументы (аргументы в python 3)
Цель: получение результата вычислений для дальнейшего использования. Случай: любая функция, которая должна предоставить данные вызывающему коду.
Как вернуть несколько значений из функции?
Python позволяет вернуть несколько значений в виде кортежа (или другого контейнера).
def min_max(numbers):
return min(numbers), max(numbers)
mn, mx = min_max([3, 1, 7, 2])
print(mn, mx) # 1 7аргумент параметр python (аргументы и параметры в python)
Распаковка кортежа позволяет присвоить каждый элемент отдельной переменной. Если не распаковать, получится кортеж.
Как функция может вернуть None?
Функция без return или с return без значения возвращает None.
def greet(name):
print(f'Привет, {name}!')
g = greet('Анна')
print(g) # Noneаргумент класса python (аргументы класса python)
Это может быть неожиданным, если ожидается возвращаемое значение. Для явного указания return None не обязательно, но улучшает читаемость.
Типичная ошибка: забыть написать return и получить None вместо ожидаемого результата. Решение: всегда проверять, возвращает ли функция значение, и добавлять return, если нужно.
Как вернуть значение из рекурсивной функции?
В рекурсивной функции каждый вызов должен передавать результат через return по цепочке до начального вызова.
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
print(factorial(5)) # 120Python аргументы строки (аргументы строки в python (командная строка))
Без return в базовом случае и в рекурсивном шаге результат не дойдёт до вызывающей стороны.
Как вернуть значение из генератора (yield)?
Генератор вместо return использует yield для возврата последовательности значений. Сам генератор возвращает итератор, а каждое следующее значение получается через next() или цикл.
def count_up_to(n):
i = 1
while i <= n:
yield i
i += 1
for num in count_up_to(3):
print(num) # 1 2 3аргумент метода python (аргументы метода python)
При завершении генератора выбрасывается исключение StopIteration. Если в генераторе встретится return с выражением, оно становится значением исключения (используется редко).
Как вернуть значение по условию?
Оператор return может находиться внутри условных конструкций, возвращая разные значения в зависимости от ситуации.
def abs_value(x):
if x >= 0:
return x
else:
return -x
print(abs_value(-5)) # 5Python args (аргументы в python)
Можно также использовать тернарный оператор:return x if x >= 0 else -x.
Как вернуть значение из вложенной функции (замыкания)?
Внутренняя функция может вернуть значение, которое будет использовано внешней функцией.
def make_multiplier(factor):
def multiplier(x):
return x * factor
return multiplier
double = make_multiplier(2)
print(double(5)) # 10именованные аргументы функции python (именованные аргументы функции python)
Возвращаемое значение - сама внутренняя функция (замыкание). Её вызов вернёт результат умножения.
Как вернуть значение из lambda-функции?
Лямбда-функция неявно возвращает результат выражения.
add = lambda a, b: a + b
print(add(3, 4)) # 7именованные аргументы python (именованные аргументы python)
Лямбда может возвращать только одно выражение, без инструкций. Если нужно несколько действий, следует использовать обычную функцию.
Как вернуть изменяемый объект (список, словарь) и избежать побочных эффектов?
При возврате изменяемого объекта, если его потом модифицировать, изменения затронут и объект внутри функции (если не сделана копия).
def get_list():
return [1, 2, 3]
lst = get_list()
lst.append(4)
print(lst) # [1, 2, 3, 4]
# исходный список внутри функции не изменился, т.к. возвращается ссылка на новый объектколичество аргументов функции python (количество аргументов функции python)
Проблема:
def add_to_list(item, lst=[]):
lst.append(item)
return lst
Использование изменяемого аргумента по умолчанию приводит к сохранению состояния между вызовами. Решение - использовать None и создавать новый список внутри.
Ошибка: возврат глобальной переменной и её изменение вне функции. Это затрудняет отладку. Лучше передавать данные через аргументы и возвращать результат.
Расширенные примеры возврата значений
1. Возврат функции (замыкание с параметрами)
def create_power_func(exponent):
def power(base):
return base ** exponent
return power
square = create_power_func(2)
cube = create_power_func(3)
print(square(4)) # 16
print(cube(2)) # 8
16 8
Каждый вызов create_power_func создаёт новую функцию с сохранённым значением exponent.
2. Возврат кортежа с именованными полями (namedtuple)
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
def midpoint(p1, p2):
return Point((p1.x + p2.x) / 2, (p1.y + p2.y) / 2)
a = Point(0, 0)
b = Point(10, 10)
m = midpoint(a, b)
print(m.x, m.y) # 5.0 5.0
5.0 5.0
Именованные кортежи улучшают читаемость кода по сравнению с обычными кортежами.
3. Возврат словаря с несколькими результатами
def analyze_numbers(data):
return {
'sum': sum(data),
'mean': sum(data) / len(data) if data else None,
'max': max(data),
'min': min(data)
}
result = analyze_numbers([1, 5, 3, 9])
print(result['mean']) # 4.5
4.5
4. Рекурсивный обход дерева с возвратом значений
def tree_sum(node):
if node is None:
return 0
return node['value'] + tree_sum(node.get('left')) + tree_sum(node.get('right'))
tree = {
'value': 1,
'left': {'value': 2, 'left': None, 'right': None},
'right': {'value': 3, 'left': None, 'right': None}
}
print(tree_sum(tree)) # 6
6
5. Генераторная функция с yield и return
def gen_with_return():
yield 1
yield 2
return 'done'
g = gen_with_return()
print(next(g)) # 1
print(next(g)) # 2
try:
next(g)
except StopIteration as e:
print(e.value) # 'done'
1 2 done
Значение, переданное return в генераторе, становится атрибутом исключения StopIteration.
6. Возврат значения из функции, модифицирующей аргумент (безопасная копия)
def add_element_safe(lst, element):
new_lst = lst[:] # копия
new_lst.append(element)
return new_lst
original = [1, 2]
modified = add_element_safe(original, 3)
print(original) # [1, 2]
print(modified) # [1, 2, 3]
[1, 2] [1, 2, 3]
7. Возврат True/False для проверки условий (функция-предикат)
def is_palindrome(s):
return s == s[::-1]
print(is_palindrome('radar')) # True
print(is_palindrome('hello')) # False
True False
8. Возврат None в особых случаях (например, ошибка)
def safe_divide(a, b):
if b == 0:
return None
return a / b
print(safe_divide(10, 2)) # 5.0
print(safe_divide(10, 0)) # None
5.0 None