Python mutable default arguments

В python’е значения функции по умолчанию создаются в момент выполнения инструкции def, а не при каждом вызове функции. Если значение - неизменяемый объект (например строка, целое число, кортеж), то никаких подводных камней здесь нет. А вот если объект изменяемый (например список), то есть возможность попасть в ловушку. Вот пример:

def foo(l=[]):
    l.append('x')
    return l

Казалось бы, при каждом вызове foo() будет возвращаться список [‘x’]. Но:

>>> foo()
['x']
>>> foo()
['x', 'x']
>>> foo()
['x', 'x', 'x']

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

def bar(l=None):
    if l is None:
        l = []
    l.append('x')
    return l

Однако, иногда этот эффект может быть полезен. Вот способ узнать сколько раз функция была вызвана:

from itertools import count

def bar(call_count=count()):
    return next(call_count)

>>> bar()
0
>>> bar()
1
>>> bar()
2
>>> bar()
3