В функциях иногда полезно указывать значение по умолчанию для одного или нескольких параметров (аргументов). Для параметра функции со значением по умолчанию, соответствующий аргумент может быть опущен при вызове. Это создает функцию, которую можно вызывать с меньшим количеством аргументов, чем предписано. Например:
def ask_ok(prompt, retries=4, reminder='Попробуйте еще раз!'): while True: ok = input(prompt) if ok in ('ok', 'y', 'yes'): return True if ok in ('n', 'no'): return False retries = retries - 1 if retries < 0: raise ValueError('Неверный ответ пользователя') print(reminder)
Эта функция может быть вызвана несколькими способами:
ask_ok('Хочешь продолжить?')
ask_ok('OK, чтобы перезаписать файл?', 2)
ask_ok('OK, чтобы перезаписать файл?', 2, 'Вводите только "ok" или "no"!')
В этом примере также вводится in
ключевое слово. Этот оператор проверяет, содержит ли последовательность определенное значение.
Если при вызове функции значение аргумента, соответствующего ключевому (именованному) параметру, не было задано, то при выполнении функции идентификатор параметра связывается с его значением по умолчанию, то есть с одним и тем же объектом.
Значения по умолчанию вычисляются в точке выполнения инструкции def
, а не в точке ее вызова, так что
i = 5 def f(arg=i): print(arg) i = 6 f() # напечатает 5.
Важное предупреждение: Значения параметров по умолчанию создаются при определении функции, а НЕ каждый раз, когда она вызывается в коде программы. Это означает, что эти выражение вычисляется один раз, и что для каждого вызова используется одно и то же предварительно вычисленное значение. Если функция изменяет объект (например, путем добавления элемента в список, словарь), значение по умолчанию фактически изменяется. Например, следующая функция накапливает аргументы, переданные ей при последующих вызовах:
def f(a, L=[]): L.append(a) return L print(f(1)) print(f(2)) print(f(3)) # Это напечатает [1] [1, 2] [1, 2, 3]
Это вообще не то, что было задумано. Способ обойти это - использовать None
по умолчанию и явно проверить его в теле функции, например вы можете написать такую функцию:
def f(a, L=None): if L is None: L = [] L.append(a) return L
Разумеется, возможны случаи, когда вам действительно нужно, чтобы заданное по умолчанию значение параметра изменилось. Чаще всего этим пользуются для кэширования данных, чтобы по возможности избежать повторного выполнения трудоемких вычислений.