Позиционные параметры функций Python: полный обзор

Раздел: 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)

Решение – всегда проверять сигнатуру функции или добавлять значения по умолчанию.

Как передать произвольное количество позиционных аргументов?

Используйте *args в определении функции. Параметр args соберёт все переданные позиционные аргументы в кортеж.
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
Вместо *args можно передать список и распаковать его при вызове:
numbers = [1, 2, 3]
print(sum_all(*numbers))
Результат:
6
Ошибка: если после *args указать ещё один позиционный параметр, он станет обязательным только для именованной передачи (keyword-only). Например:
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
Частая проблема – попытка передать именованный аргумент как позиционный, не соблюдая порядок. Ошибка: create_profile('Пётр', country='Беларусь', 30) – синтаксическая ошибка, так как позиционные не могут идти после именованных.

Как использовать аннотации типов для позиционных аргументов?

Аннотации помогают документировать ожидаемые типы. Они не проверяются во время выполнения, но могут быть использованы инструментами вроде mypy.
def greet(name: str, age: int = 0) -> str:
    return f'{name}, возраст {age}'
Вызов с разными типами всё равно выполнится, но IDE предупредит о несоответствии.
print(greet('Анна', 'двадцать'))  # синтаксически верно, но логически неверно
Можно использовать Union или Optional из typing:
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() или срезы.

Дополнительные аспекты и расширенное использование

Позиционные аргументы можно комбинировать с *args и **kwargs для построения гибких API.
def wrapper(func, *args, **kwargs):
    print('Вызов функции с позиционными:', args)
    print('Именованные:', kwargs)
    return func(*args, **kwargs)
Пример вызова:
def divide(a, b):
    return a / b
wrapper(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.

Позиционные аргументы в Python - comments

En
Positional argument python (python)