python
October 12, 2021

Подводные камни использования изменяемых типов в функциях Python

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

Так, изменяемый тип создается в момент объявления функции и модифицируется при каждом обращении к ней (конечно, если в теле это предусмотрено). Объявим функцию и вызовем ее с разными аргументами:

def f(a, l=[]):
    l.append(a)
    return l
f(1)
f(2)

Как можно заметить, второй вызов привел к выводу списка, включающего оба элемента (1 и 2).

Такое поведение изменяемых типов иногда полезно использовать. Например, мы можем задать локальный кэш для своих данных, когда операции их получения трудоемки. Снова объявим функцию:

def cache_op(a,b, cache={}):
    if (a,b) in cache:
        res = cache[(a,b)]
    else:
        res = a**b
        cache[(a,b)] = res
    return res

Далее вызовем ее дважды с одними и теми же аргументами и замерим скорость в обоих случаях:

%%time
cache_op(200001,200001)

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