Зарегистрируйтесь, чтобы продолжить обучение

Именованные параметры Python: Функции

Существует несколько методов передачи данных в функции, и одним из базовых является использование позиционных параметров.

Позиционные параметры работают на основе их порядка в определении функции. Когда мы вызываем функцию и передаем ей значения, они подставляются в параметры в том же порядке, в котором они определены в функции.

def add(x, y):
    return x + y

Напомним, что параметры это имена в определении функции: x и y. А аргументы это значения, что подставляются при вызове. В этом случае с аргументами (10, 20) параметр x получит значение 10, а y20.

Но в Python у функций могут быть еще и именованные аргументы — keyword arguments. Их применять особенно удобно для вызова функций с множеством параметров одного типа.

Например, мы вызываем следующую функцию:

def calculate(base, sub, mul):
    return (base - sub) * mul

У функции calculate() три параметра - основное значение (base), значение, что вычитается и значение, на которое происходит умножение. При вызове этой функции, например calculate(10, 3, 2), может быть неочевидно сразу, где какой параметр, ведь их несколько и они одного, числового, типа.

В таком случае мы можем вызвать функцию с именованными аргументами. Чтобы передать именованные аргументы в функцию, нужно указать их имена, которые были заданы при объявлении функции:

# без пояснения неясно где какой параметр
calculate(10, 3, 2) # 14

# в таком вызове уже очевидно где какой параметр
calculate(base=10, sub=3, mul=2) # 14

# также мы можем передавать аргументы в любом порядке
calculate(mul=2, sub=3, base=10) # 14

При вызове функции меняется порядок передаваемых аргументов. Когда функции назначаются соответствующие значения именованных аргументов, Python учитывает их имена, а не позиции. В результате функция будет всегда выводить одно и то же значение независимо от позиций переданных ей аргументов.

Нет строгих правил, по которым используются именованные аргументы. Однако широко практикуется такой подход: если функция принимает больше трех аргументов, нужно хотя бы часть из них указать по имени. Важно именовать аргументы, если несколько значений имеют одинаковый тип. В другом случае будет трудно понять, что делает функция с подобным вызовом:

make('circle', 300, 150, 10, None, 2.5, False)

Сравните с этим:

make(
    shape='circle',
    x=300, y=150, radius=10,
    line_pattern=None,
    line_width=2.5,
    fill=False
)

Такой код читать проще.

Значения параметров по умолчанию

Иногда в функции параметры задаются с одними и теми же значениями. Так функцией открытия файлов open() чаще открывают их в режиме чтения, а функция print() добавляет перенос строки. В такой ситуации удобно указать значения по умолчанию:

def calculate(base, sub, mul=1):
    return (base - sub) * mul

# если передается аргумент, то используется переданное значение
calculate(10, 3, 2) # 14

# если не передается, то используется значение по умолчанию
calculate(10, 3) # 7

Можно сочетать вызов с позиционным и именованными аргументами. Главное, порядок групп аргументов — позиционные значения должны быть указаны до именованных, иначе мы получим ошибку.

calculate(base=10, 3)
# => SyntaxError: positional argument follows keyword argument

Изменяемые объекты как параметры по умолчанию

Python при использовании значений по умолчанию сохраняет их внутри объекта функции. При каждом вызове функции возвращаются сохраненные значения и подставляются в параметр.

Посмотреть сохраненные значения можно через метод __defaults__:

def greet(name="User", greeting="Hello"):
    return f"{greeting}, {name}!"

print(greet.__defaults__)  # ('User', 'Hello')

Потому важно не использовать изменяемые коллекции и объекты, ведь они будут сохранять все изменения между вызовами функции.

def add_scores(score, scores=[]):
    scores.append(score)
    return scores

add_scores(10) # [10]
add_scores(20) # [10, 20]
add_scores(30) # [10, 20, 30]

Правильным подходом будет создавать изменяемый объект в функции, а по умолчанию передавать None:

def add_scores(score, scores=None):
    if scores is None:
        scores = []  # создаем новый список при каждом вызове
    scores.append(score)
    return scores

add_scores(10) # [10]
add_scores(10) # [10]
add_scores(10) # [10]

Keyword-only параметры

В Python есть возможность пометить параметры функции так, чтобы вызывать функцию можно было только передавая в них значения по именам. Такие параметры называются keyword-only, строго именованные, и в них нельзя передать позиционные аргументы. Выглядит функция с подобными параметрами так:

def open_file(name, *, writable=False, binary=False):
    

f1 = open_file('foo.txt', writable=True)
f2 = open_file('bar.bin', binary=True)
f3 = open_file('raw.dat', True, True)
# TypeError: open_file() takes 1 positional argument but 3 were given

Здесь * выступает разделителем — отделяет обычные параметры от строго именованных. Такой разделитель можно использовать только один раз в одном определении. Также можно объявлять функции, у которых будут только строго именованные параметры. Для этого нужно поставить звездочку в самом начале перечня параметров.

Пример выше демонстрирует подход к описанию параметров. Первый параметр — имя файла, который будет открыт. Оно всегда присутствует и связано по смыслу с именем функции. Поэтому этот параметр можно не именовать. А writable и binary — необязательные параметры, которые получают значения True/False. Если бы их передавали без указания имени, то было бы непонятно какой к чему относится. Поэтому опции и объявлены так, что могут быть указаны только явно и по имени.

Выводы

В этом уроке мы узнали, что у функций в Python кроме позиционных есть еще и именованные аргументы. Также мы научились использовать их. Они нужны, когда мы хотим изменить порядок размещения передаваемых аргументов.

Важно запомнить, что для передачи именованных аргументов в функцию, нужно указать их имена, которые были заданы при объявлении функции. Когда функции назначаются значения именованных аргументов, Python учитывает их имена, а не позиции.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 25 000 ₸ в месяц
Разработка веб-приложений на Django
10 месяцев
с нуля
Старт 27 февраля

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»