Позиционные параметры функций Python: полный обзор
Основы позиционных аргументов в Python
Что такое позиционные аргументы и как они работают?
def show_info(name, age, city):
print(f'{name}, {age} лет, {city}')Python определение функции (определение функции в python)
Вызов с правильным порядком:show_info('Алексей', 30, 'Москва')Positional argument python (позиционные аргументы в python)
Результат:Алексей, 30 лет, Москва
базовые коды в python (базовые коды на python)
show_info(city='Москва', age=30, name='Алексей')запись переменных в python (объявление и запись переменных в python)
Это не меняет сути позиционных, но позволяет переставить аргументы местами при вызове.show_info('Алексей', 30) # TypeError: missing 1 required positional argument: 'city'как закоментить несколько строк в python (комментирование блоков кода в python)
Решение – всегда проверять сигнатуру функции или добавлять значения по умолчанию.Как передать произвольное количество позиционных аргументов?
def sum_all(*args):
return sum(args)несколько значений в переменной python (присваивание нескольких значений переменным в python)
Вызов с разным числом аргументов:print(sum_all(1, 2, 3))новая переменная в python (создание новой переменной в python)
Результат:6
print(sum_all(10, 20, 30, 40))Результат:100
numbers = [1, 2, 3]
print(sum_all(*numbers))Результат:6
def func(*args, extra):
print(args, extra)Вызов func(1,2,3,4) вызовет ошибку, нужно писать func(1,2,3, extra=4).Как правильно сочетать позиционные и именованные аргументы?
def create_profile(name, age, country='Россия', language='русский'):
print(f'{name}, {age}, {country}, {language}')Вызов с обязательными позиционными и необязательными именованными:create_profile('Мария', 25)Результат:Мария, 25, Россия, русский
def connect(*, host, port):
print(f'Подключение к {host}:{port}')Такие аргументы нельзя передать позиционно – только по имени:connect(host='localhost', port=8080) # верно
connect('localhost', 8080) # TypeError: takes 0 positional argumentsКак использовать аннотации типов для позиционных аргументов?
def greet(name: str, age: int = 0) -> str:
return f'{name}, возраст {age}'Вызов с разными типами всё равно выполнится, но IDE предупредит о несоответствии.print(greet('Анна', 'двадцать')) # синтаксически верно, но логически неверноfrom typing import Union, Optional
def process(value: Union[int, str], flag: Optional[bool] = None):
passКак распаковать последовательность в позиционные аргументы при вызове функции?
def point(x, y, z):
print(f'Координаты: {x}, {y}, {z}')Список или кортеж:coords = [10, 20, 30]
point(*coords)Результат:Координаты: 10, 20, 30
def three_letters(a, b, c):
print(a, b, c)three_letters(*'ABC')Результат:A B C
three_letters(*(x for x in range(3)))Результат:0 1 2
point(*[1, 2]) # TypeError: missing 1 required positional argumentПеред распаковкой убедитесь в длине последовательности, используйте len() или срезы.Дополнительные аспекты и расширенное использование
def wrapper(func, *args, **kwargs):
print('Вызов функции с позиционными:', args)
print('Именованные:', kwargs)
return func(*args, **kwargs)Пример вызова:def divide(a, b):
return a / bwrapper(divide, 10, 2)Результат:Вызов функции с позиционными: (10, 2)
Именованные: {}
5.0Продвинутые примеры с позиционными аргументами
Использование позиционных аргументов в декораторах
Декоратор может перехватывать позиционные аргументы для логирования или модификации.
def log_args(func):
def wrapper(*args, **kwargs):
print(f'Аргументы: {args}, {kwargs}')
return func(*args, **kwargs)
return wrapper
@log_args
def multiply(a, b, c):
return a * b * c
print(multiply(2, 3, 4))Аргументы: (2, 3, 4), {}
24Передача позиционных аргументов из списка с частичной распаковкой
Можно распаковать только часть списка, используя комбинацию позиционных и *args.
def show(first, second, *others):
print(f'first: {first}, second: {second}, others: {others}')
values = [10, 20, 30, 40, 50]
show(*values)first: 10, second: 20, others: (30, 40, 50)
Сортировка с помощью аргументов, передаваемых позиционно
Функция sorted принимает аргументы key и reverse как именованные, но позиционные аргументы в ней – это сама последовательность.
data = ['они', 'я', 'мы', 'вы']
print(sorted(data, key=len))['я', 'мы', 'вы', 'они']
Здесь позиционный аргумент – список, а key – именованный.
Использование functools.partial для фиксации позиционных аргументов
partial позволяет заранее зафиксировать часть позиционных аргументов.
from functools import partial
def power(base, exp):
return base ** exp
square = partial(power, exp=2)
cube = partial(power, exp=3)
print(square(5)) # 25
print(cube(2)) # 8Обратите внимание: partial может работать как с позиционными, так и с именованными. Если фиксировать позиционные, нужно передавать их в том же порядке.
Позиционные аргументы с изменяемыми объектами
Если позиционным аргументом является mutable объект (список, словарь), то изменения внутри функции влияют на оригинал.
def add_element(lst, element):
lst.append(element)
return lst
my_list = [1, 2]
new_list = add_element(my_list, 3)
print(my_list) # [1, 2, 3]
print(new_list) # [1, 2, 3]Это может быть неожиданностью, если не копировать объект внутри функции.
Аннотации типов с позиционными аргументами в классах
class Person:
def __init__(self, name: str, age: int = 0):
self.name = name
self.age = age
p = Person('Ольга', 28)
print(p.name, p.age)Ольга 28
Позиционные аргументы в lambda-функциях
add = lambda x, y: x + y
print(add(3, 7))10
Lambda поддерживает только позиционные и именованные аргументы, без *args.