Кортеж ведет себя как неизменный список. Тот факт, что вы записываете их в скобки, возможно, сбивает с толку, но это более или менее совпадение - результат того факта, что скобки используются для группировки вещей и уменьшая неоднозначность в противном случае.
Когда вы вызываете функцию, вы не предоставляете кортеж. Вы предоставляете аргументы. Кортеж может быть аргументом, но только одним - это просто переменная типа tuple
.
Что вы можете сделать, это развернуть кортеж (или список) в серию аргументов с такой нотацией:
tup = (2, 3)
f(*tup)
# expand the tuple (2,3) into a series of arguments 2, 3
Вы можете сделать это и со словарями, кроме как с **
вместо *
:
my_dict = {"arg1": 1, "arg2": 2}
f(arg1=my_dict["arg1"], arg2=my_dict["arg2"])
f(**my_dict) # these are equivalent
С другой стороны, функции могут принимать произвольное количество аргументов (аналогично тому, как другие языки делают для вызовов printf()
). Например:
def g(*args):
print("I got this many arguments:", len(args))
Здесь, если вы делаете type(args)
, вы получаете tuple
, а если вы делаете type(*args)
, вы получаете ошибку. Это связано с тем, что в заголовках функций *
делает прямо противоположное: упаковывает аргументы, переданные функции, в один кортеж, чтобы вы могли работать с ними. Учтите следующее:
g(2, 3) # 2 arguments, both integers
g((2, 3)) # 1 argument, a tuple
g(*(2, 3)) # 2 arguments, both integers
Короче говоря,
- функции построены таким образом, что они принимают произвольное количество аргументов
- Операторы
*
и **
могут распаковывать наборов / списков / диктов в аргументы на одном конце и упаковывать их на другом конце
- отдельные кортежи / списки / дикты - это просто отдельные переменные.