Аргументы функций Python: способы передачи и примеры
Основные способы передачи аргументов
Наиболее универсальное решение: комбинирование *args и **kwargs
Оно позволяет принимать произвольное количество позиционных и именованных аргументов. Используется в декораторах, обёртках и функциях, где набор параметров заранее не известен.
def wrapper(func, *args, **kwargs):
print("Вызов функции")
return func(*args, **kwargs)
def add(a, b):
return a + b
print(wrapper(add, 3, 5))аргументы print python (аргументы функции print в python)
Вызов функции 8
Python 3 аргументы (аргументы в python 3)
Проблемы: при неправильной передаче именованных аргументов возникает TypeError. Также нужно следить за совместимостью сигнатуры целевой функции.
Как передать аргументы, полагаясь только на их порядок?
Позиционные аргументы передаются в том же порядке, в котором объявлены параметры.
def greet(name, greeting):
return f"{greeting}, {name}!"
print(greet("Анна", "Привет"))аргумент параметр python (аргументы и параметры в python)
Привет, Анна!
аргумент класса python (аргументы класса python)
Типичная ошибка:
Передача аргументов в неверном порядке приводит к логическим ошибкам. Например, greet("Привет", "Анна") вернёт "Анна, Привет!" – порядок слов нарушен.
Решение: всегда документировать порядок или использовать именованные аргументы.
Как сделать код более читаемым, явно указывая имена параметров?
Именованные аргументы передаются с указанием имени параметра. Они делают вызов самодокументированным.
print(greet(name="Иван", greeting="Здравствуйте"))Python аргументы строки (аргументы строки в python (командная строка))
Здравствуйте, Иван!
аргумент метода python (аргументы метода python)
Типичная ошибка:
Передача именованного аргумента, которого нет в определении функции, вызывает TypeError: unexpected keyword argument. Проверяйте имена.
Как задать аргументы, которые можно не указывать?
Значения по умолчанию присваиваются параметрам при определении функции. Если аргумент не передан, используется значение по умолчанию.
def connect(host, port=8080):
return f"{host}:{port}"
print(connect("localhost"))
print(connect("localhost", 9090))Python args (аргументы в python)
localhost:8080 localhost:9090
именованные аргументы функции python (именованные аргументы функции python)
Классическая ошибка:
Изменяемые объекты (список, словарь) в качестве значения по умолчанию. Они создаются один раз при определении функции и могут накапливать изменения между вызовами.
def append_to(element, lst=[]):
lst.append(element)
return lst
print(append_to(1))
print(append_to(2))именованные аргументы python (именованные аргументы python)
[1] [1, 2] # Ошибка: список разделяется между вызовами
количество аргументов функции python (количество аргументов функции python)
Решение: использовать None как значение по умолчанию и создавать новый объект внутри функции.
def append_to(element, lst=None):
if lst is None:
lst = []
lst.append(element)
return lstпараметры и аргументы функции python (параметры и аргументы функции python)
Как позволить функции принимать неограниченное количество значений?
Параметр *args собирает все лишние позиционные аргументы в кортеж.
def sum_all(*args):
return sum(args)
print(sum_all(1, 2, 3, 4))Python передать аргументы (передача аргументов в python)
10
Python принять аргументы (приём аргументов в python)
Ошибка:
Если после *args объявить ещё позиционные параметры, их можно передать только как именованные (keyword-only). Иначе возникает TypeError.
Как передать произвольный набор ключевых аргументов?
Параметр **kwargs собирает все избыточные именованные аргументы в словарь.
def print_config(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_config(db="sqlite", host="localhost", port=5432)Python список аргументов (список аргументов в python)
db: sqlite host: localhost port: 5432
Python тип аргумента (тип аргумента в python)
Проблема:
Если функция уже ожидает конкретные именованные аргументы, **kwargs может поглотить их все, и ошибка не возникнет, если передать лишние. Нужна явная проверка.
Как сделать некоторые параметры только именованными, запретив их передачу по позиции?
Аргументы, объявленные после *, являются keyword-only. Они могут быть переданы только по имени.
def divide(a, b, *, integer=False):
result = a / b
if integer:
result = int(result)
return result
print(divide(10, 3, integer=True))Python return value (возвращаемое значение функции в python)
3
абсолютное значение python (абсолютное значение в python)
Ошибка:
Попытка передать keyword-only аргумент по позиции: divide(10, 3, True) – TypeError: divide() takes 2 positional arguments but 3 were given.
Как использовать все возможности одновременно?
Комбинирование позиционных, *args, keyword-only и **kwargs.
def complicated(a, b, *args, opt=None, **kwargs):
print("a:", a, "b:", b)
print("args:", args)
print("opt:", opt)
print("kwargs:", kwargs)
complicated(1, 2, 3, 4, opt="value", extra="test")вернуть значение функции python (возврат значения из функции в python)
a: 1 b: 2
args: (3, 4)
opt: value
kwargs: {'extra': 'test'}
Типичная путаница:
Порядок объявления параметров строг: сначала позиционные, затем *args, затем keyword-only, затем **kwargs. Нарушение порядка приведёт к синтаксической ошибке.
Расширенные примеры передачи аргументов
Декоратор с произвольными аргументами
Декоратор, который логирует вызов любой функции, используя *args и **kwargs.
import functools
def logger(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(f"Вызов {func.__name__} с args={args}, kwargs={kwargs}")
return func(*args, **kwargs)
return wrapper
@logger
def add(x, y):
return x + y
print(add(3, 5))
print(add(x=10, y=20))
Вызов add с args=(3, 5), kwargs={}
8
Вызов add с args=(), kwargs={'x': 10, 'y': 20}
30
Частичное применение с functools.partial
Частичное применение фиксирует часть аргументов функции, возвращая новую функцию с уменьшенным числом параметров.
from functools import partial
def power(base, exponent):
return base ** exponent
square = partial(power, exponent=2)
cube = partial(power, exponent=3)
print(square(5))
print(cube(2))
25 8
Распаковка списков и словарей при вызове
Операторы * и ** можно использовать не только в определении функции, но и при её вызове для распаковки коллекций.
def point(x, y, z):
return f"({x}, {y}, {z})"
coords = [1, 2, 3]
dict_coords = {'x': 10, 'y': 20, 'z': 30}
print(point(*coords))
print(point(**dict_coords))
(1, 2, 3) (10, 20, 30)
Это позволяет динамически формировать аргументы из структур данных.
Аннотации типов и их получение
Современный Python поддерживает аннотации аргументов и возвращаемого значения. Информацию можно получить через __annotations__.
def greet(name: str, age: int = 18) -> str:
return f"{name} ({age} лет)"
print(greet.__annotations__)
{'name': , 'age': , 'return': }
Аннотации не проверяются автоматически, но используются сторонними инструментами (mypy, IDE).
Принудительная проверка типов в рантайме
С помощью декоратора можно проверять типы аргументов, используя аннотации.
def type_check(func):
import functools
@functools.wraps(func)
def wrapper(*args, **kwargs):
hints = func.__annotations__
# Сопоставить позиционные аргументы по именам параметров
for name, value in zip(func.__code__.co_varnames, args):
if name in hints and not isinstance(value, hints[name]):
raise TypeError(f"Аргумент {name} должен быть {hints[name]}")
for name, value in kwargs.items():
if name in hints and not isinstance(value, hints[name]):
raise TypeError(f"Аргумент {name} должен быть {hints[name]}")
return func(*args, **kwargs)
return wrapper
@type_check
def add(a: int, b: int) -> int:
return a + b
print(add(3, 5))
# print(add(3, "5")) # TypeError
8
Переменное число аргументов и позиционные после звездочки
Можно комбинировать *args с одним обязательным именованным параметром, используя синтаксис keyword-only после *. Пример: функция, принимающая любое количество чисел и флаг сортировки.
def process(*numbers, sort_result=False):
if sort_result:
return sorted(numbers)
return list(numbers)
print(process(3, 1, 2, sort_result=True))
print(process(5, 4, 3))
[1, 2, 3] [5, 4, 3]