Вызов может осуществляться при помощи позиционных и/или именованных аргументов.
Аргумент — значение, передаваемое в функцию/метод при её/его вывозе.

Внимание
Аргументы и параметры — две разные сущности, которые не следует путать между собой.

При вызове аргументы перечисляются через запятую ,.

После вызова значения аргументов становятся доступными из локальных (в теле функции) переменных.

В Питоне существуют два типа аргументов:

  • Позиционные
  • Именованные

Именованные аргументы


На заметку
Обычно используется сокращённое название — kwargs (keyword arguments).

Это аргументы, передаваемые в вызов при помощи имени (идентификатора), либо словаря с его распаковкой при помощи **.

# Здесь 3 и 5 - именованные аргументы.
complex(real=3, imag=5)
complex(**{'real': 3, 'imag': 5})

Позиционные аргументы


На заметку
Обычно используется сокращённое название — args (arguments).

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

# Здесь 3 и 5 - позиционные аргументы.
complex(3, 5)
complex(*(3, 5))

Механизм обработки аргументов


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

Если указаны именованные аргументы, то они приводятся к позиционным описанным далее способом.

1. Создаётся список пустых слотов по числу формальных параметров. Если существует N позиционных аргументов, то они будут помещены в первые N слотов. Далее для каждого именованного аргумента его имя используется для определения соответствующего слота (например, если имя совпадает с первым именем параметра, то используется первый слот и т.д.).

2. Если слот уже заполнен, возбуждается TypeError. В иных случаях значение аргумента помещается в слот (даже если при вычислении выражения получено None).

def func(a, b):
print(a, b)


func(a=1, **{'a': 2})
# func() got multiple values for keyword argument 'a'

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

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

def func(a, b, d=3, e=[]):
e.append(0)
print(a, b, d, e)


func(1, b=2, e=[4]) # 1 2 3 [4, 0]
func(1, 2) # 1 2 3 [0]
func(1, 2) # 1 2 3 [0, 0]
func(1, 2) # 1 2 3 [0, 0, 0]

4. Если после этого остались незаполненные слоты, для которых не указано значение по умолчанию, возбуждается TypeError. Иначе заполненный список слотов используется в качестве списка аргументов для вызова.

На заметку
Детали реализации CPython. Существуют встроенные функции, позиционные аргументы которых в реальности не имеют имён, хотя могут быть проименованы в документации. Поэтому такие аргументы не могут быть адресованы как именованные. Примерами таких функций могут служить функции реализованные на Си, использующие PyArg_ParseTuple() для разбора аргументов.


Распаковка


Наверняка вам встречались записи вида *args, **kwargs при вызове функций. Звездочки в этом случае указывают на то, что объект дожен быть «распакован» в набор аргументов для вызываемой функции.

1. Если позиционных аргументов больше, чем слотов для формальных параметров и при этом не используется распаковка вида *имя, возбуждается TypeError. Если распаковка используется, то формальный параметр получает кортеж с избыточными позиционными аргументами (кортеж будет пустым, если избытка не наблюдается).

2. Если для любого из именованных аргументов не нашлось соответствующего по имени формального параметра и при этом не используется распаковка вида **имя, возбуждается TypeError. Если распаковка используется, то формальный параметр получает словарь с избыточными именованными аргументами (словарь будет пустым, если избытка не наблюдается).

Если используется распаковка вида *выражение, то выражение должно вычисляться в объект, поддерживающий итерирование. В этом случае элементы объекта трактуются как дополнительные позиционные аргументы. Если существуют позиционные аргументы x1, ..., xN и выражение вычисляется в последовательность y1, ..., yM — это эквивалентно вызову с позиционными аргументами M+N: x1, ..., xN, y1, ..., yM.

На заметку
Как следствие из вышесказанного: хотя распаковка вида *выражение может употребляться ПОСЛЕ именованных аргументов, обрабатывается такое выражение всё же ДО (то же касается и **выражение, о чём будет сказано ниже). Впрочем, на практике именованные аргументы не часто встречаются вместе с *выражение в одном вызове, а потому такие недоразумения редки.

def func(a, b):
print(a, b)

add_args = (2,)
func(b=1, *add_args) # 2 1
func(a=1, *add_args) # TypeError
func(1, *add_args) # 1 2

Если используется распаковка вида **выражение, то выражение должно вычисляться в отображение, содержимое которого трактуется как дополнительные позиционные аргументы. Если имя будет обнаружено и в результате выражения и в явном указании аргумента, возбуждается TypeError.

def func(a, b):
print(a, b)


func(a=1, **{'a': 2})
# func() got multiple values for keyword argument 'a'

Ограничение на количество аргументов


  • Начиная с +py3.7, количество аргументов, которые могут быть приняты функцией явно ограничено лишь стеком. До этого существовало ограничение в 255 элементов, при нарушении которого возбуждалось SyntaxError.
  • При использовании функцией *args, **kwargs, количество ограничено значением из sys.maxsize.
Синонимы поиска: Аргументы вызова, аргументы, позиционные, именованные, *args, **kwargs
В разделе «Callable (вызываемый)»: def (функция/метод) Параметры вызываемых объектов
На заметку
Зарегистрированные пользователи могут публиковать свои мнения относительно Книг, Видео, Статей других авторов и прочего в разделе Обсуждений.