JavaRush /Курсы /Модуль 1: Python Core /Продвинутая работа с параметрами функций

Продвинутая работа с параметрами функций

Модуль 1: Python Core
8 уровень , 6 лекция
Открыта

7.1 Получение всех аргументов функции

В языке Python есть несколько очень удобных способов получить изнутри функции список всех переданных в неё параметров. Давайте пройдемся по ним.

Использование *args

*args позволяет передавать переменное количество позиционных (обычных) аргументов в функцию. Эти аргументы упаковываются в кортеж и могут быть обработаны внутри функции.


def print_numbers(*args):
    for arg in args:
        print(arg)
        
print_numbers(1, 2, 3, 4, 5)

Объяснение

Функция print_numbers принимает произвольное количество позиционных аргументов, упакованных в кортеж args. Мы можем перебирать аргументы внутри функции с помощью цикла for.

Преимущества

  • Гибкость: Позволяет передавать любое количество аргументов в функцию.
  • Универсальность: Может быть использовано для функций с неопределённым числом параметров.

Использование **kwargs

**kwargs позволяет передавать переменное количество именованных аргументов в функцию. Эти аргументы упаковываются в словарь и могут быть обработаны внутри функции.


def print_person_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")
        
print_person_info(name="Alice", age=30, city="New York")

Объяснение

Функция print_person_info принимает произвольное количество именованных аргументов, упакованных в словарь kwargs. Мы можем перебирать аргументы внутри функции с помощью метода словаря items().

Преимущества

  • Гибкость: Позволяет передавать любое количество именованных аргументов в функцию.
  • Читаемость: Именованные аргументы делают вызовы функций более читаемыми.

7.2 Фиксирование типа аргументов

Только позиционные аргументы

В Python 3.8 и выше можно определять функции с позиционными аргументами, которые можно передавать только по позиции. Это делается с помощью символа / в определении функции.


def greet(name, /, greeting="Hello"):
    print(f"{greeting}, {name}!")
        
greet("Alice")  # Вывод: Hello, Alice!
greet("Alice", greeting="Hi")  # Вывод: Hi, Alice!
# greet(name="Alice")  # Ошибка: TypeError

Объяснение

Функция greet принимает аргумент name, который можно передать только по позиции. Аргументы перед / могут быть переданы только по позиции.

Такой подход позволяет ограничить способ передачи аргументов, улучшая читаемость и предотвращая ошибки.

Только именованные аргументы (Keyword-Only Arguments)

Также можно определить параметры функции, которые можно передавать только по имени. Это делается с помощью символа * в определении функции.


def greet(*, name, greeting="Hello"):
    print(f"{greeting}, {name}!")
        
greet(name="Alice")  # Вывод: Hello, Alice!
greet(name="Alice", greeting="Hi")  # Вывод: Hi, Alice!
# greet("Alice")  # Ошибка: TypeError

Функция greet принимает аргумент name, который можно передать только по имени. Аргументы после * могут быть переданы только по имени.

Такой подход заставляет явно указывать имена аргументов, улучшая читаемость кода.

Комбинирование позиционных и именованных аргументов

Также можно комбинировать позиционные и именованные аргументы для достижения максимальной гибкости.


def greet(name, /, *, greeting="Hello"):
    print(f"{greeting}, {name}!")
        
greet("Alice")  # Вывод: Hello, Alice!
greet("Alice", greeting="Hi")  # Вывод: Hi, Alice!
# greet(name="Alice")  # Ошибка: TypeError

Функция greet принимает аргумент name, который можно передать только по позиции, и именованный аргумент greeting, который обязательно должен быть передан по имени. Использование и / и * позволяет комбинировать позиционные и именованные аргументы.

Полный пример всех трех ситуаций:


def full_example(a, b, /, c, d, *, e, f):
    print(f"a={a}, b={b}, c={c}, d={d}, e={e}, f={f}")
        
# Вызов функции с различными аргументами
full_example(1, 2, 3, 4, e=5, f=6)  # Все аргументы переданы корректно
# full_example(a=1, b=2, c=3, d=4, e=5, f=6)  # Ошибка: TypeError

Пояснение

  • Позиционные только аргументы: a и b должны быть переданы только по позиции.
  • Обычные позиционные или именованные аргументы: c и d могут быть переданы как по позиции, так и по имени.
  • Именованные только аргументы: e и f должны быть переданы только по имени.
2
Задача
Модуль 1: Python Core, 8 уровень, 6 лекция
Недоступна
Бесконечность не предел.
Бесконечность не предел.
2
Задача
Модуль 1: Python Core, 8 уровень, 6 лекция
Недоступна
Бесконечное количество имен.
Бесконечное количество имен.
Комментарии (12)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
shinobi Уровень 19
30 июля 2025
Намеренно не вчитывался в лекцию, потому что задания к ней - контрл ц контрл в И похер, что эти задания даже к этому уровню не относятся, и вставлены для галочки И похер, что пример в лекции - 1в1 решение для задачи ниже, и думать вообще не нужно. Качество материала такое ужасное, что уже стараешься ни на что внимание не обращать. Не знаю будет ли лучше дальше.
web_dream Уровень 15
16 октября 2025
Начал заглядывать в комментарии исключительно чтобы прочитать такие комментарии xD
Дмитрий Уровень 27
25 февраля 2025
Передал в первой задаче в sum генератор. А вот фиг - не принимается задача, чёрным по экранному написано "произвольное количество чисел", а вовсе не генератор. Хотя всё работает, разумеется, и считает правильно. И если в функцию передать "произвольное количество чисел" - тоже работает.

def sum_numbers(*args):
    return sum(*args) # успешно применяем sum к генератору

print(sum_numbers((x for x in range(1,10)))) # передаём вместо списка - генератор

a = [1,2,3,4,5,6,7,8,9] # а теперь делаем список
print(sum_numbers(a)) # и передаём его
Но не принимается валидатором.
4 марта 2025
args без * нужно видимо, у меня так приняло
Mr.Robot Уровень 21 Expert
6 марта 2025
В *args передается переменное количество аргументов, которые упаковываются в кортеж уже в процессе выполнения кода. Уже готовые списки или кортежи в *args вставлять нельзя. Ну, то есть, можно - компиллятор просто будет делать кортеж списков, типа такого: ([1, 2, 3, 4],) В этом случае вычисление суммы будет давать ошибку типа, т.к. список будет суммироваться с int
Mr.Robot Уровень 21 Expert
6 марта 2025
Ну и у генератора - тоже на выходе список или кортеж в зависимости от генератора. Тоже не будет считать
Дмитрий Уровень 27
12 марта 2025
Разобрался я с этим фокусом. Если внимательно читать доки, то можно обнаружить, что астериск-оператор при определении функции упаковывает данные в кортеж, а при вызове функции распаковывает данные из кортежа. Таким образом

def func(*abc):
упаковывает аргументы в кортеж, а

sum(*def)
распаковывает кортеж, или список, и передаёт аргументы в функцию. Например:

c = ([1,2,3,4,5,6,7,8,9],)
print(sum(*c)) #Output: 45

c = [[1,2,3,4,5,6,7,8,9]]
print(sum(*c)) #Output: 45
Двойной астериск ** работает аналогично. Поэтому фокус

def abc(*def):
    return sum(*def)
работает с генераторами и списками, передаваемыми в функцию abc, хоть это и бессмысленно без анализа переданных аргументов.
Slevin Уровень 64
1 июля 2025
*args - произвольное количество аргументов, но это НЕ имя переменной. args - имя кортежа созданного из аргумента (*args)
2 августа 2025
у меня приняло def sum_numbers(*args): return sum(args) num = [1, 2, 3, 4, 5] print(sum_numbers(*num))
Николай Уровень 17
19 февраля 2025
По идее это должны проходить на 6м уровне, когда функции проходили Удивлён. Пункт 7.2 достаточно редкий для курсов. Но по сути только полезный для чтения документаций (что тоже очень важный)
Dmitry Ryabov Уровень 23
2 февраля 2025
Нет задач, посвященных фиксированию типов переменных
Аркадий Уровень 44
8 октября 2024
Как то странно после декораций.) над 2 задачей нужно задуматься.