Документация по Python

Функции в Python

Функции в Python
В: Документация по Python

Определение и вызов простых функций

Использование def утверждения является наиболее распространенным способом определить функцию в Python. Это утверждение так называемое соединение заявление одного пункта со следующим синтаксисом:

def function_name(parameters):
    statement(s)

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

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

statement(s) - также известное как тело функции - это непустое последовательность операторов , выполняемых при каждом вызове функции. Это означает , что тело функции не может быть пустым, так же как и любой отступом блок .

Вот пример простого определения функции, целью которой является для печати Hello каждый раз , когда это называется:

def greet():
    print("Hello")

Теперь давайте называть определенные greet() функции:

greet()
# Hello

Это еще один пример определения функции, которая принимает один единственный аргумент и отображает переданное значение каждый раз, когда вызывается функция:

def greet_two(greeting):
    print(greeting)

 

После того, что greet_two() функция должна быть вызвана с аргументом:

greet_two("Howdy")
# Howdy

Также вы можете задать значение по умолчанию для этого аргумента функции:

def greet_two(greeting="Howdy"):
  print(greeting)

Теперь вы можете вызывать функцию без указания значения:

greet_two()

# Howdy 

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

def many_types(x):
  if x < 0:
    return "Hello!"
  else:
    return 0

print(many_types(1))
print(many_types(-1))

# 0
# Hello!

Пока это правильно обрабатывается вызывающей стороной, это совершенно правильный код Python.

Функция , которая достигает конца исполнения без оператора возврата всегда будет возвращать None :

def do_nothing():
  pass

print(do_nothing())
# None

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

Возвращение значений из функций

Функции могут return значение , которое можно использовать непосредственно:

def give_me_five():
  return 5

print(give_me_five())  # Распечатать возвращенное значение
# 5

 

или сохраните значение для последующего использования:

num = give_me_five()
print(num)             # Распечатать сохраненное возвращаемое значение
# 5

 

или используйте значение для любых операций:

print(give_me_five() + 10)
# 15

Если return встречается в функции функция будет немедленно вышла и последующие операции не будут оцениваться:

def give_me_another_five():
    return 5
    print('Это заявление не будет напечатано. Когда-либо.')

print(give_me_another_five())
# 5

Вы также можете return несколько значений (в виде кортежа):

def give_me_two_fives():
    return 5, 5  # возвращает две 5

first, second = give_me_two_fives()
print(first)
# 5
print(second)
# 5

 

Функция, без return заявления неявно возвращает None.Точно так же функция с return утверждением, но не возвращает значение или переменная возвращает None .

Определение функции с аргументами

Аргументы определены в скобках после имени функции:

def divide(dividend, divisor):  #Имена функции и ее аргументы
  # Аргументы доступны по имени в теле функции
  print(dividend / divisor)

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

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

divide(10, 2)
# 5

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

divide(divisor=2, dividend=10)
# 5 

Определение функции с необязательными аргументами

Дополнительные аргументы могут быть определены путем назначения ( с использованием = ) значение по умолчанию имя-аргумента:

def make(action='nothing'):
  return action

Вызов этой функции возможен тремя различными способами:

make("fun")
# fun

make(action="sleep")
# sleep

# Аргумент является необязательным, поэтому функция 
# будет использовать значение по умолчанию, 
# если аргумент не передан.
make()   
# ничего не происходит

Предупреждение

Изменяемые типы ( list , dict , set и т.д.) , следует относиться с осторожностью , когда дается как атрибут по умолчанию. Любая мутация аргумента по умолчанию изменит его навсегда. См Определение функции с дополнительными изменяемыми аргументами .

Определение функции с несколькими аргументами

Можно дать функции столько аргументов, сколько нужно, единственные фиксированные правила - это то, что каждое имя аргумента должно быть уникальным и что необязательные аргументы должны быть после не необязательных:

def func(value1, value2, optionalvalue=10):
  return '{0} {1} {2}'.format(value1, value2, optionalvalue)

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

print(func(1, 'a', 100))
# 1 a 100

print(func('abc', 14))
# abc 14 10

 

Или совмещать указание аргументов с именем и без. Тогда те, у кого есть имя, должны следовать за теми, у кого нет, но порядок тех, у кого есть имя, не имеет значения:

print(func('This', optionalvalue='StackOverflow Documentation', value2='is'))
# This is StackOverflow Documentation 

Произвольное количество позиционных аргументов:

Определение функции , способную принимать произвольное количество аргументов может быть сделано с помощью префиксов один из аргументов с *

def func(*args):
    # args будет кортежем, содержащим все переданные значения
    for i in args:
        print(i)

# Вызов с 3 аргументами
func(1, 2, 3)  
# 1
# 2
# 3

list_of_arg_values = [1, 2, 3]

# Вызов со списком значений, * расширяет список
func(*list_of_arg_values)
# 1
# 2
# 3 

# Вызов без аргументов
func()
# Нет вывода 

Вы не можете предоставить по умолчанию для args , например func(*args=[1, 2, 3]) поднимет синтаксическую ошибку (даже не компилировать).

Вы не можете обеспечить их по имени при вызове функции, например func(*args=[1, 2, 3]) поднимет TypeError .

Но если у вас уже есть свои аргументы в массиве (или любой другой Iterable ), вы можете вызвать вашу функцию следующим образом: func(*my_stuff) .

Эти аргументы ( *args ) можно обращаться по индексу, например , args[0] возвращает первый аргумент

Произвольное количество аргументов ключевого слова

Вы можете принимать произвольное число аргументов с именем, определяя аргумент в определении с двумя * перед ним:

def func(**kwargs):
    # kwargs будет словарем, содержащим имена 
    # в качестве ключей и значения в качестве значений.
    for name, value in kwargs.items():
        print(name, value)

# Вызов с 3-мя аргументами
func(value1=1, value2=2, value3=3)
# value1 1
# value2 2
# value3 3

# Вызов без аргументов
func()                               
# Нет вывода

# Вызов по словарю
my_dict = {'foo': 1, 'bar': 2}
func(**my_dict)                     
# foo 1
# bar 2

 

Вы не можете предоставить это без имен, например func(1, 2, 3) поднимет TypeError .

kwargs это простой родной словарь питона. Например, args['value1'] даст значение аргумента value1.Обязательно проверьте заранее , что есть такой аргумент или KeyError будет поднят.

Предупреждение

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

  • Позиционные / ключевые аргументы приходят в первую очередь. (Обязательные аргументы).  
  • Потом приходит произвольные *arg аргументы. (Необязательный).  
  • Потом приходят аргументы ключевых слов только. (Необходимые).  
  • Последнее приветиходит  произвольные ключевое слово **kwargs  (Необязательный).
# |-positional-|-optional-|---keyword-only--|-optional-|
def func(arg1, arg2=10 , *args, kwarg1, kwarg2=2, **kwargs):
     pass
  • arg1 должен быть задан, в противном случае TypeError поднимается. Это может быть задано как позиционный ( func(10) ) или ключевым словом аргумента ( func(arg1=10) ).
  • kwarg1 также должен быть предоставлен, но она может быть обеспечена только в качестве ключевого слова-аргумента: func(kwarg1=10) .
  • arg2 и kwarg2 не являются обязательными. Если значение должно быть изменено тем же правилам , как и для arg1 (либо позиционной или ключевое слово) и kwarg1 (только ключевое слово) применяются.
  • *args уловы дополнительные позиционные параметры. Но обратите внимание, что arg1 и arg2 должны быть предоставлены в качестве позиционных аргументов передать аргументы *args : func(1, 1, 1, 1) .
  • **kwargs перехватывает все дополнительные параметры ключевых слов. В этом случае любой параметр , который не arg1 , arg2 , kwarg1 или kwarg2.Например: func(kwarg3=10) .
  • В Python 3, вы можете использовать * в покое , чтобы указать , что все последующие аргументы должны быть указаны в качестве ключевых слов. Для экземпляра math.isclose функции в Python 3.5 и выше , определяется с использованием def math.isclose (a, b, *, rel_tol=1e-09, abs_tol=0.0) , что означает , что первые два аргумента могут быть поставлены позиционно , но по желанию третий и четвертый параметры могут быть предоставлены только как ключевые аргументы.

Python 2.x не поддерживает параметры только для ключевых слов. Такое поведение можно эмулировать с kwargs :

def func(arg1, arg2=10, **kwargs):
  try:
    kwarg1 = kwargs.pop("kwarg1")
  except KeyError:
    raise TypeError("missing required keyword-only argument: 'kwarg1'")
  kwarg2 = kwargs.pop("kwarg2", 2)
  # function body ...

Примечание по именованию

Условность наименования необязательных позиционных аргументов args и необязательных аргументы ключевых слов kwargs просто условность вы можете использовать любые имена вам нравится , но это полезно следовать соглашению , чтобы другие знали , что вы делаете, или даже сам потом так пожалуйста.

Обратите внимание на уникальность

Любая функция может быть определена ни с одной или *args и ни один или один **kwargs , но не более чем с одним из каждых. Также *args должен быть последним аргументом позиционного и **kwargs должен быть последним параметром. Попытка использовать более одного либо приведет к исключению ошибок синтаксиса.

Замечание о функциях вложения с необязательными аргументами

Можно гнездовые такие функции и обычная условность, чтобы удалить элементы , что код уже обрабатываемые , но если вы передаете вниз параметры , которые нужно передать дополнительные позиционные аргументы с * префиксом и необязательной ключевыми словами арг с ** приставкой , иначе аргументы будут передаваться как список или кортеж, а kwargs - как один словарь. например:

def fn(**kwargs):
  print(kwargs)
  f1(**kwargs)

def f1(**kwargs):
  print(len(kwargs))

fn(a=1, b=2)

# {'a': 1, 'b': 2}
# 2 

Определение функции с необязательными изменяемыми аргументами

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

Объяснение

Эта проблема возникает из - за аргументов функции по умолчанию инициализируются один раз, в тот момент , когда функция определена, а не (как и многие другие языки) , когда функция вызывается. Значения по умолчанию сохраняется в функции объект __defaults__ переменного члена.

def f(a, b=42, c=[]):
    pass

print(f.__defaults__)
# (42, [])

Для неизменяемых типов (см передачи аргументов и переменчивости ) это не проблема , потому что нет никакого способа , чтобы мутировать переменные; это может только быть переназначено, оставляя оригинальное значение неизменным. Следовательно, последующие гарантированно будут иметь одинаковое значение по умолчанию. Однако, для изменяемого типа, исходное значение может мутировать, делая звонки на его различные функции - членов. Следовательно, последовательные вызовы функции не гарантируют начальное значение по умолчанию.

def append(elem, to=[]):
  # Этот вызов append() изменяет переменную по умолчанию "to"
  to.append(elem)
  return to

append(1)
# [1]

# Добавляет его во внутренний список
append(2)  
# [1, 2]

# Использование вновь созданного списка дает ожидаемый результат
append(3, [])  
# [3]

# Повторный вызов без аргументов снова добавит
# список к внутреннему списку
append(4)   
# [1, 2, 4]

Решение

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

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

def append(elem, to=None):
  if to is None:
    to = []
    
  to.append(elem)
  return to

Лямбда функции

lambda ключевое слово создает функцию инлайн, содержащую одно выражение. Значение этого выражения - это то, что функция возвращает при вызове.

Рассмотрим функцию:

def greeting():
  return "Hello"

который, когда называется как:

print(greeting())

 

печатает:

# Hello

Это можно записать в виде лямбда-функции следующим образом:

greet_me = lambda: "Hello"

 

Это создает встраиваемую функцию с именем greet_me , который возвращает Hello.Обратите внимание , что вы не пишете return при создании функции с лямбда. Значение после : автоматически возвращается.

После присвоения переменной она может использоваться как обычная функция:

print(greet_me())

 

печатает:

# Hello

lambda - s может принимать аргументы, тоже:

strip_and_upper_case = lambda s: s.strip().upper()
strip_and_upper_case("  Hello   ")

возвращает строку:

# HELLO

Они также могут принимать произвольное количество аргументов / ключевых слов, как обычные функции.

greeting = lambda x, *args, **kwargs: print(x, args, kwargs)
greeting('hello', 'world', world='world')

 

печатает:

# hello('world',) {'world': 'world'}

lambda - ы обычно используются для коротких функций, которые удобно определить в точке , где они называются ( как правило , с sorted , filter и map ).

Например, эта строка сортирует список строк, игнорируя их регистр и игнорируя пробелы в начале и в конце:

sorted( [" foo", "    bAR", "BaZ    "], key=lambda s: s.strip().upper())
 
# ['   bAR', 'BaZ   ', 'foo']

Список сортировки просто игнорируя пробелы:

sorted( [" foo", "    bAR", "BaZ    "], key=lambda s: s.strip())

# ['BaZ   ', '  bAR', 'foo']

Примеры с map :

Примеры с числовыми списками:

my_list = [3, -4, -2, 5, 1, 7]
sorted( my_list, key=lambda x: abs(x))

# [1, -2, 3, -4, 5, 7]

list( filter( lambda x: x>0, my_list))

# [3, 5, 1, 7]

list( map( lambda x: abs(x), my_list))

[3, 4, 2, 5, 1, 7]

Другие функции (с / без аргументов) можно вызывать внутри лямбда-функции.

def foo(msg):
    print(msg)

greet = lambda x = "hello world": foo(x)
greet()

 

печатает:

hello world

 

Это полезно , потому что lambda может содержать только одно выражение и с помощью дочерней функции можно запустить несколько операторов.

Передача аргумента и изменчивость

Сначала немного терминологии:

  • аргумент (фактический параметр): фактическая переменная передается в функцию;
  • параметр (формальный параметр): принимающая переменная, которая используется в функции.

В Python, аргументы передаются по заданию (в отличие от других языков, где аргументы могут передаваться по значению / задания / указателя).

Мутирование параметра приведет к изменению аргумента (если тип аргумента является изменяемым).

def foo(x):   # здесь х параметр
    x[0] = 9  # Это мутирует 1ый элемент x, 
    		  # так и первый элемент y задаваемый ниже
    print(x)

y = [4, 5, 6]
foo(y)        # вызвать foo с y в качестве аргумента
# [9, 5, 6]   # список, помеченный x, был изменен
print(y)           
# [9, 5, 6]   # список, помеченный y, тоже был видоизменен

Переназначение параметра не переназначит аргумент.

def foo(x):        # здесь x - параметр, когда мы вызываем
				   # foo(y), мы присваиваем y значению x
    x[0] = 9       # Это мутирует список, как x, так и y
    x = [1, 2, 3]  # x теперь помечает другой список 
				   # (y не затрагивается)
    x[2] = 8       # Это мутирует список x, а не список y

y = [4, 5, 6]      # y is the argument, x is the parameter
foo(y)             # Представьте, что мы написали «x = y», 
			 	   # затем перейдите к строке 1.
y
# [9, 5, 6] 

В Python, мы на самом деле не присваивать значения переменным, вместо того, чтобы мы связываем (то есть переуступать, присоединять) переменные (рассматриваемые как имена) к объектам.

  • Неизменные: Целые, строки, кортежи, и так далее. Все операции делают копии.
  • Mutable: списки, словари, наборы, и так далее. Операции могут или не могут мутировать.
x = [3, 1, 9]
y = x
x.append(5)    # Изменяет список, помеченный x и y,
			   # оба x и y привязаны к [3, 1, 9]
x.sort()       # Изменяет список, помеченный x и y
			   # (сортировка на месте)
               
x = x + [4]    # Не изменяет список (создает копию 
			   # только для x, а не для y)

z = x          # z равно x([1, 3, 9, 4])
x += [6]       # Изменяет список, помеченный как x,
			   # так и z (использует функцию расширения).
               
x = sorted(x)  # Не изменяет список (создает копию для x)
x
# [1, 3, 4, 5, 6, 9]

y
# [1, 3, 5, 9]

z
# [1, 3, 5, 9, 4, 6] 

Return

Замыкания в Python создаются вызовами функций. Здесь вызов makeInc создает привязку для x , ссылка внутри функции inc.Каждый вызов makeInc создает новый экземпляр этой функции, но каждый экземпляр имеет ссылку на другую связыванию x .

def makeInc(x):
  def inc(y):
    # x "присоединен" к определению inc
    return y + x
  return inc

incOne = makeInc(1)
incFive = makeInc(5)

incOne(5) 
# 6

incFive(5)
# 10

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

def makeInc(x):
  def inc(y):
    # увеличение x не разрешено
    x += y
    return x
  return inc

incOne = makeInc(1)
incOne(5) 
# UnboundLocalError: local variable 'x' referenced before assignment

Python 3 предлагает nonlocal заявление  для реализации полного закрытия с вложенными функциями.

def makeInc(x):
  def inc(y):
    nonlocal x # теперь можно присвоить значение x
    x += y
    return x
  return inc

incOne = makeInc(1)
incOne(5) 

# 6

Рекурсивные функции

Рекурсивная функция - это функция, которая вызывает себя в своем определении. Например, математическая функция, факториала, определяется factorial(n) = n*(n-1)*(n-2)*...*3*2*1.может быть запрограммирован как

def factorial(n):
  #n здесь должно быть целым числом
  if n == 0:
    return 1
  else:
    return n*factorial(n-1)

выходы здесь:

factorial(0)
#1

factorial(1)
#1

factorial(2)
#2

factorial(3)
# 6

как и ожидалось. Обратите внимание , что эта функция является рекурсивной , потому что второй return factorial(n-1) , где функция называет себя в своем определении.

Некоторые рекурсивные функции могут быть реализованы с помощью лямбда , факториала с помощью лямбда - бы что - то вроде этого:

factorial = lambda n: 1 if n == 0 else n*factorial(n-1)

 

Функция выводит то же, что и выше.

Предел рекурсии

Существует предел глубины возможной рекурсии, который зависит от реализации Python. Когда предел достигнут, возникает исключение RuntimeError:

def cursing(depth):
  try:
    cursing(depth + 1) # actually, re-cursing
  except RuntimeError as RE:
    print('I recursed {} times!'.format(depth))

cursing(0)
# I recursed 998 times! 

Можно изменить рекурсии предел глубины, используя sys.setrecursionlimit(limit) и проверить этот предел sys.getrecursionlimit() .

import sys 

sys.setrecursionlimit(2000)
cursing(0)
# I recursed 1998 times! 

Из Python 3.5, исключение составляет RecursionError , который является производным от RuntimeError .

Вложенные функции

Функции в Python являются первоклассными объектами. Они могут быть определены в любой области

def fibonacci(n):
  def step(a,b):
    return b, a+b
  a, b = 0, 1
  for i in range(n):
    a, b = step(a, b)
  return a

Функции захвата их охватывающей области видимости могут передаваться как любой другой вид объекта

def make_adder(n):
  def adder(x):
    return n + x
  return adder
  
add5 = make_adder(5)
add6 = make_adder(6)
add5(10)
#15

add6(10)
#16

def repeatedly_apply(func, n, x):
  for i in range(n):
    x = func(x)
  return x

repeatedly_apply(add5, 5, 1)
# 26 

Итерация и распаковка словаря

Функции позволяют указывать следующие типы параметров: позиционные, именованные, переменные позиционные, аргументы ключевых слов (kwargs). Вот четкое и краткое использование каждого типа.

def unpacking(a, b, c=45, d=60, *args, **kwargs):
    print(a, b, c, d, args, kwargs)

unpacking(1, 2)
# 1 2 45 60 () {}

unpacking(1, 2, 3, 4)
# 1 2 3 4 () {}

unpacking(1, 2, c=3, d=4)
# 1 2 3 4 () {}

unpacking(1, 2, d=4, c=3)
# 1 2 3 4 () {}

pair = (3,)
unpacking(1, 2, *pair, d=4)
# 1 2 3 4 () {}

unpacking(1, 2, d=4, *pair)
# 1 2 3 4 () {}

unpacking(1, 2, *pair, c=3)
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# TypeError: unpacking() got multiple values for argument 'c'

unpacking(1, 2, c=3, *pair)
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# TypeError: unpacking() got multiple values for argument 'c'

args_list = [3]
unpacking(1, 2, *args_list, d=4)
# 1 2 3 4 () {}

unpacking(1, 2, d=4, *args_list)
#1 2 3 4 () {}

unpacking(1, 2, c=3, *args_list)
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# TypeError: unpacking() got multiple values for argument 'c'

unpacking(1, 2, *args_list, c=3)
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# TypeError: unpacking() got multiple values for argument 'c'

pair = (3, 4)
unpacking(1, 2, *pair)
# 1 2 3 4 () {}

unpacking(1, 2, 3, 4, *pair)
# 1 2 3 4 (3, 4) {}

unpacking(1, 2, d=4, *pair)
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# TypeError: unpacking() got multiple values for argument 'd'

unpacking(1, 2, *pair, d=4)
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# TypeError: unpacking() got multiple values for argument 'd'

args_list = [3, 4]
unpacking(1, 2, *args_list)
# 1 2 3 4 () {}

unpacking(1, 2, 3, 4, *args_list)
# 1 2 3 4 (3, 4) {}

unpacking(1, 2, d=4, *args_list)
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# TypeError: unpacking() got multiple values for argument 'd'

unpacking(1, 2, *args_list, d=4)
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# TypeError: unpacking() got multiple values for argument 'd'

arg_dict = {'c':3, 'd':4}
unpacking(1, 2, **arg_dict)
# 1 2 3 4 () {}

arg_dict = {'d':4, 'c':3}
unpacking(1, 2, **arg_dict)
# 1 2 3 4 () {}

arg_dict = {'c':3, 'd':4, 'not_a_parameter': 75}
unpacking(1, 2, **arg_dict)
# 1 2 3 4 () {'not_a_parameter': 75

unpacking(1, 2, *pair, **arg_dict)
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# TypeError: unpacking() got multiple values for argument 'd'

unpacking(1, 2, 3, 4, **arg_dict)
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# TypeError: unpacking() got multiple values for argument 'd'

# Позиционные аргументы имеют приоритет 
# над любой другой формой передачи аргументов

unpacking(1, 2, **arg_dict, c=3)
# 1 2 3 4 () {'not_a_parameter': 75}

unpacking(1, 2, 3, **arg_dict, c=3)
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# TypeError: unpacking() got multiple values for argument 'c' 

Принудительное использование именованных параметров

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

def f(*a, b):
    pass

f(1, 2, 3)
# TypeError: f() missing 1 required keyword-only argument: 'b'


 

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

def f(a, b, *, c):
    pass

f(1, 2, 3)
# TypeError: f() takes 2 positional arguments but 3 were given
f(1, 2, c=3)
# No error 

Еще от кодкамп
Оглавление
Замечательно! Вы успешно подписались.
Добро пожаловать обратно! Вы успешно вошли
Вы успешно подписались на кодкамп.
Срок действия вашей ссылки истек.
Ура! Проверьте свою электронную почту на наличие волшебной ссылки для входа.
Успех! Ваша платежная информация обновлена.
Ваша платежная информация не была обновлена.