Python позволяет указать, что аргумент функции является необязательным, предоставив для него значение по умолчанию. Хотя это отличная особенность языка, она может привести к некоторой путанице, когда значение по умолчанию является изменяемым. Например, рассмотрим определение такой функции:
>>> def foo(bar=[]):... bar.append('baz')... return barРаспространенной ошибкой является мысль, что для необязательного аргумента будет задано указанное выражение по умолчанию каждый раз, когда вызывается функция, без указания значения для необязательного аргумента. Например, в приведенном выше коде можно ожидать, что повторный вызов foo() всегда будет возвращать ['baz'], поскольку предполагается, что каждый раз, когда вызывается foo(), bar установлен на [].
>>> foo()['baz']>>> foo()['baz', 'baz']>>> foo()['baz', 'baz', 'baz']Ответ на вопрос “почему так происходит?” заключается в том, что значение по умолчанию для аргумента функции создается только один раз, во время определения функции. Таким образом, аргумент bar инициализируется по умолчанию только тогда, когда foo() определен впервые, но затем вызовы foo() продолжат использовать тот же список для какой bar был изначально инициализирован.
Чаще всего такую ситуацию обходят примерно следующим образом:
>>> def foo(bar=None):... if bar is None:... bar = []... bar.append('baz')... return bar... >>> foo()['baz']>>> foo()['baz']>>> foo()['baz']# test