когда стадия определения функции?
Посмотрите на "Определения функций" в справочнике по Python:
Значения параметров по умолчанию оцениваются при выполнении определения функции. Это означает, что выражение вычисляется один раз, когда функция определена, и что одно и то же «предварительно вычисленное» значение используется для каждого вызов. Это особенно важно понимать, когда параметр по умолчанию является изменяемым объектом, таким как список или словарь: если функция изменяет объект (например, путем добавления элемента в список), значение по умолчанию в действительности изменяется. Это вообще не то, что было задумано. Чтобы обойти это, используйте None
в качестве значения по умолчанию и явно проверьте его в теле функции, например ::
def whats_on_the_telly(penguin=None):
if penguin is None:
penguin = []
penguin.append("property of the zoo")
return penguin
Параметры оцениваются при выполнении определения функции . Если это в модуле, это происходит, когда модуль импортируется. Если это в классе, это когда определение класса выполняется. Если это в функции, это происходит, когда функция выполняется. Помните, что модуль Python оценивается сверху вниз и автоматически не имеет явной «основной функции», как некоторые языки.
Например, если вы поместите определение функции внутри функции, вы будете получать новую копию функции каждый раз:
>>> def make_function():
... def f(value=[]):
... value.append('hello')
... return value
... return f
...
>>> f1 = make_function()
>>> f2 = make_function()
>>> f1()
['hello']
>>> f1()
['hello', 'hello']
>>> f2()
['hello']
Определение функции создает новый объект function
, присваивает ему различные свойства, включая код, формальные параметры и значения по умолчанию, и сохраняет его в имени в области. Обычно это происходит только один раз для любой данной функции, но есть случаи, когда определение функции может быть выполнено снова.
Первоначально я думал, что имя a_list удаляется сразу после запуска функции, поэтому все, что мутирует []
, будет собирать мусор.
Внутри тела функции для кода доступно имя a_list
. Таким образом, имя и значение, на которое оно указывает, оба должны быть доступны. Он сохраняется в атрибуте func_defaults
функции.
Но опять же, мне интересно, как я получаю то же значение по умолчанию вместо нового [].
Поскольку []
оценивается только тогда, когда определена функция, а не когда она вызывается, а имя a_list
указывает на один и тот же объект даже при повторных вызовах. Опять же, если вам нужно альтернативное поведение, используйте что-то неизменное, например None
, и проверьте его.