Основы описания функций и их вызов в Python
Основное определение функции в Python
Функция в Python создается с помощью ключевого слова def, за которым следует имя функции, круглые скобки с параметрами (если они нужны) и двоеточие. Тело функции записывается с отступом (обычно 4 пробела). Для возврата значения используется оператор return. Если return не указан, функция возвращает None.
def say_hello():
print('Привет, мир!')
say_hello()Python определение функции (определение функции в python)
Привет, мир!
Positional argument python (позиционные аргументы в python)
Имя функции должно начинаться с буквы или подчеркивания и содержать только буквы, цифры и подчеркивания. Регистр имеет значение.
Варианты определения функций
Как определить функцию с одним аргументом?
Аргумент указывается в скобках. При вызове функции необходимо передать значение.
def greet(name):
return f'Здравствуйте, {name}!'
print(greet('Анна'))
базовые коды в python (базовые коды на python)
Здравствуйте, Анна!
запись переменных в python (объявление и запись переменных в python)
Как создать функцию, которая принимает несколько аргументов?
Аргументы перечисляются через запятую. Они называются позиционными, если порядок их передачи важен.
def add(a, b):
return a + b
print(add(3, 5))как закоментить несколько строк в python (комментирование блоков кода в python)
8
несколько значений в переменной python (присваивание нескольких значений переменным в python)
Как задать значения аргументов по умолчанию?
Параметры со значениями по умолчанию записываются как param=value. Они могут быть опущены при вызове.
def multiply(a, b=2):
return a * b
print(multiply(5)) # b=2
print(multiply(5, 3)) # b=3новая переменная в python (создание новой переменной в python)
10 15
Проблема: изменяемый объект (например, список) в качестве значения по умолчанию сохраняется между вызовами функции. Решение: использовать None и создавать объект внутри функции.
def append_to(element, lst=None):
if lst is None:
lst = []
lst.append(element)
return lst
print(append_to(1))
print(append_to(2))
[1] [2]
Как работать с произвольным количеством позиционных аргументов?
Используется *args - параметр с одной звездочкой, который собирает все переданные позиционные аргументы в кортеж.
def sum_all(*args):
return sum(args)
print(sum_all(1, 2, 3, 4))
10
Как передавать произвольное количество именованных аргументов?
Используется **kwargs - две звездочки, аргументы собираются в словарь.
def print_info(**kwargs):
for key, value in kwargs.items():
print(f'{key}: {value}')
print_info(name='Алиса', age=30, city='Москва')
name: Алиса age: 30 city: Москва
Как объединить позиционные и именованные аргументы в одной функции?
Порядок: обычные параметры, *args, параметры только по ключу, **kwargs.
def func(a, b, *args, debug=False, **kwargs):
print(f'a={a}, b={b}')
print(f'args: {args}')
print(f'debug: {debug}')
print(f'kwargs: {kwargs}')
func(1, 2, 3, 4, debug=True, extra='test')
a=1, b=2
args: (3, 4)
debug: True
kwargs: {'extra': 'test'}
Как вернуть несколько значений из функции?
Возвращается кортеж значений через запятую. Развернуть можно в несколько переменных.
def min_max(numbers):
return min(numbers), max(numbers)
low, high = min_max([4, 2, 9, 1])
print(f'Минимум: {low}, Максимум: {high}')
Минимум: 1, Максимум: 9
Как определить анонимную функцию (лямбда)?
Лямбда-функция - это короткая функция без имени, записываемая в одну строку. Используется как аргумент других функций.
square = lambda x: x ** 2
print(square(5))
# Применение с map
numbers = [1, 2, 3]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)
25 [1, 4, 9]
Как добавить документацию к функции?
Сразу после заголовка функции записывается строковый литерал (docstring). Он доступен через атрибут __doc__.
def circle_area(radius):
"""Вычисляет площадь круга по радиусу."""
import math
return math.pi * radius ** 2
print(circle_area.__doc__)
help(circle_area)
Вычисляет площадь круга по радиусу. ...(справка)
Как использовать аннотации типов для параметров и возвращаемого значения?
После двоеточия у параметра указывается тип, после стрелки -> - тип возвращаемого значения. Это не влияет на выполнение, но помогает статическим анализаторам.
def add(a: int, b: int) -> int:
return a + b
print(add(2, 3))
5
Как определить рекурсивную функцию?
Рекурсивная функция вызывает саму себя. Важно задать базовый случай для остановки рекурсии.
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
print(factorial(5))
120
Проблема: превышение глубины рекурсии для больших чисел. Решение: увеличить лимит с помощью sys.setrecursionlimit() или использовать итеративный подход.
Как создать вложенную функцию (замыкание)?
Функция может быть определена внутри другой функции. Внутренняя функция имеет доступ к переменным внешней.
def make_multiplier(factor):
def multiplier(x):
return x * factor
return multiplier
double = make_multiplier(2)
print(double(5))
10
Типичные ошибки и способы их решения
- SyntaxError: отсутствие двоеточия после заголовка функции. Решение: добавить двоеточие.
- IndentationError: неверный отступ. Все строки тела функции должны иметь одинаковый отступ.
- TypeError: несоответствие количества аргументов при вызове. Решение: проверить сигнатуру и передать нужное количество.
- UnboundLocalError: попытка изменить глобальную переменную без объявления
global. Решение: объявить переменную какglobalвнутри функции.
Расширенные примеры определения функций
Пример 1. Функция для проверки простого числа с использованием рекурсии и аннотаций
def is_prime(n: int, divisor: int = None) -> bool:
"""Проверяет, является ли число n простым, рекурсивно."""
if n < 2:
return False
if divisor is None:
divisor = n - 1
if divisor == 1:
return True
if n % divisor == 0:
return False
return is_prime(n, divisor - 1)
print(is_prime(7))
print(is_prime(10))
True False
Функция принимает число n и делитель, который уменьшается на каждом шаге. Базовый случай - делитель достигает 1.
Пример 2. Функция с декоратором для логирования
def logger(func):
def wrapper(*args, **kwargs):
print(f'Вызов {func.__name__} с args={args}, kwargs={kwargs}')
result = func(*args, **kwargs)
print(f'Результат: {result}')
return result
return wrapper
@logger
def add_with_log(a, b):
return a + b
add_with_log(3, 4)
Вызов add_with_log с args=(3, 4), kwargs={}
Результат: 7
Декоратор logger оборачивает функцию, добавляя вывод до и после вызова. Это полезно для отладки.
Пример 3. Функция, принимающая как позиционные, так и именованные аргументы через распаковку
def configure(config_path: str, **options):
with open(config_path, 'w') as f:
for key, value in options.items():
f.write(f'{key}={value}\n')
print(f'Конфигурация сохранена в {config_path}')
configure('settings.cfg', host='localhost', port=8080, debug=True)
Конфигурация сохранена в settings.cfg
Функция записывает именованные параметры в файл. **options позволяет передавать любые параметры.
Пример 4. Использование лямбда-функции с filter для выборки четных чисел
numbers = [1, 4, 7, 8, 10, 13]
even = list(filter(lambda x: x % 2 == 0, numbers))
print(even)
[4, 8, 10]
Лямбда возвращает True для четных чисел, filter оставляет только их.
Пример 5. Функция с переменным числом аргументов для вычисления среднего
def average(*values):
if not values:
return 0.0
return sum(values) / len(values)
print(average(1, 2, 3, 4, 5))
print(average(10))
print(average())
3.0 10.0 0.0
Функция обрабатывает случай пустого вызова.
Пример 6. Рекурсивный обход вложенного списка с помощью функции
def flatten(nested):
result = []
for item in nested:
if isinstance(item, list):
result.extend(flatten(item))
else:
result.append(item)
return result
nested_list = [1, [2, [3, 4]], 5]
print(flatten(nested_list))
[1, 2, 3, 4, 5]
Рекурсия позволяет обработать произвольную вложенность.
Пример 7. Функция-генератор с использованием yield
def fibonacci(limit):
a, b = 0, 1
while a < limit:
yield a
a, b = b, a + b
for num in fibonacci(10):
print(num, end=' ')
0 1 1 2 3 5 8
Генератор возвращает последовательно значения, не занимая память под весь список.