Позиционные-only и keyword-only параметры в Python

Позиционные-only и keyword-only параметры в Python

@python_quiz

Разберем этот квиз

Коротко: в функции используются специальные разделители параметров — / и *. Они задают, какие аргументы можно передавать позиционно, а какие — только по имени. Ниже разберём код, варианты и покажем примеры.

Условие (код)

python

Этот фрагмент ничего не читает из файлов — строка "cfg.yaml" здесь просто значение аргумента.

Что делает / и * в сигнатуре

  • Параметры до / — позиционные только (positional-only). Их нельзя передавать как именованные аргументы.
  • Параметры после * — keyword-only. Их можно (и нужно, если нет значения по умолчанию) передавать только по имени.
  • Параметры между ними можно передавать и так, и так (не используется в этом примере).

В нашей функции:

  • path — positional-only.
  • reload — keyword-only, с дефолтным значением False.

Анализ конкретного вызова

Вызов:

python
  • 'cfg.yaml' передаётся позиционно в параметр path — это допустимо (path позиционный).
  • reload передаётся по имени — тоже допустимо (reload keyword-only).

В результате выражение внутри функции возвращает строку "cfg.yaml:R" (буква R означает, что reload=True). При print это будет напечатано как:

python

Разбор возможных альтернатив и почему они не происходят

  • Вывод "cfg.yaml:R": соответствует поведению функции при передаче reload=True — так и происходит.
  • Вывод "cfg.yaml:C": был бы при reload=False (например, при вызове load_config('cfg.yaml') без аргумента reload), но в данном вызове reload=True, поэтому вывод будет с R.
  • TypeError из‑за позиционного аргумента path: не возникает, потому что path передан позиционно (как требует /). Ошибка возникла бы только если попытаться вызвать load_config(path='cfg.yaml', reload=True).
  • TypeError из‑за keyword reload: не возникает, потому что reload — keyword-only и передан как именованный аргумент, что корректно. Ошибка возникла бы при попытке передать reload позиционно, например load_config('cfg.yaml', True).

Демонстрация альтернативных вызовов

python

Если раскомментировать последние две строки, они вызовут TypeError: первая — потому что path нельзя передавать по имени, вторая — потому что reload нельзя передавать позиционно.

Выводы — кратко и по делу

  • Символ / делает предыдущие параметры позиционными только.
  • Символ * делает последующие параметры доступными только по имени.
  • В приведённом вызове всё корректно: путь передан позиционно, флаг reload — по имени, поэтому функция выводит строку с R.

Report Page