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

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

@python_quiz

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

Короткий пример для анализа:

python

Что здесь происходит и почему код работает именно так — разберём синтаксис и варианты вызова.

Синтаксис: / и *

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

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

  • a — positional-only (из-за /).
  • b — обычный параметр (можно позиционно или по ключу).
  • c — keyword-only (из-за *).

Почему print(merge(1, b=2, c=3)) выводит 6

Вызов разбирается так:

  • a получает 1 (передан позиционно) — допустимо.
  • b получает 2 (передан по имени) — допустимо, потому что b не positional-only.
  • c получает 3 (передан по имени) — обязательно должен быть по имени, это keyword-only.

Сумма 1 + 2 + 3 = 6, поэтому на экран выводится 6.

python

Разбор возможных вариантов вызова и ошибок

Примеры корректных и некорректных вызовов с объяснениями:

1) Вызов, аналогичный исходному:

python

2) Попытка передать a по имени — вызовет TypeError, потому что a — positional-only:

python

3) Передать все позиционно — ошибка, потому что c — keyword-only:

python

4) Передать b позиционно, c по имени — корректно:

python

5) Попытка передать c позиционно и b по имени (перестановка) — приведёт к той же ошибке, что и пункт 3:

python

(Последний пример показывает, что порядок именованных аргументов не важен, если они допустимы. Но c всё равно должен быть передан по имени.)

Практические советы

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

Вывод

Синтаксис с / и * даёт тонкий контроль над тем, как параметры могут передаваться. В примере a — только позиционный, b — гибкий, c — только по ключу; такой набор делает вызов merge(1, b=2, c=3) корректным и приводит к выводу 6.

Report Page