>>> Декоратор lru_cache
Еще один полезный декоратор из модуля functools
стандартной библиотеки Python – это lru_cache(maxsize=128, typed=False)
. Этот декоратор запоминает до maxsize
последних результатов, возвращаемых декорированной функцией для различных аргументов и, в случае повторного обращения к функции с теми же аргументами, возвращает результат из кэша вместо того, чтобы вызывать функцию.
Воспользуемся им, чтобы кэшировать значения чисел Фибоначчи, рассчитанные функцией fibc
.
>>> def fib(n):
... if n < 2:
... return n
... return fib(n-1) + fib(n-2)
...
>>> fib(35) # несколько секунд...
9227465
>>>
>>> from functools import lru_cache
>>>
>>> @lru_cache(maxsize=36)
... def fibc(n):
... if n < 2:
... return n
... return fibc(n-1) + fibc(n-2)
...
>>> fibc(35) # гораздо быстрее
9227465
Декоратор lru_cache
также снабжает декорированную функцию методом cache_info
(ведь функции – тоже объекты!), который покажет статистику использования кэша:
>>> fibc.cache_info()
CacheInfo(hits=33, misses=36, maxsize=36, currsize=36)
Подробнее о декораторе lru_cache
см. документацию Python.
>>> Декоратор с параметрами
Декоратор с параметрами – это функция с параметрами, возвращающая обычный декоратор с единственным параметром-функцией:
>>> def deco_abc(a, b, c):
... def deco(fun):
... def f(*args, **kwargs):
... print(a, b, c)
... return fun(*args, **kwargs)
... return f
... print(a, b, c)
... return deco
...
>>> @deco_abc(1, 3, 7)
... def hi(name):
... return 'hi, ' + name
...
1 3 7
>>> hi('Andrei')
1 3 7
'hi, Andrei'
В данном случае декорирование функции hi
эквивалентно следующему:
>>> def hi(name):
... return 'hi, ' + name
...
>>> hi = deco_abc(1, 3, 7)(hi)
1 3 7
>>> hi('Andrei')
1 3 7
'hi, Andrei'
>>> Декоратор может
Итак, декоратор может
- добавлять в декорируемую функцию дополнительную функциональность, например, вывод на печать аргументов, или кэширование результатов, или логирование вызовов,
- как-то иначе обрабатывать функцию в процессе декорирования, например, регистрировать декорируемую функцию в качестве обработчика некоторого события, в качестве теста или в ином качестве.
Дополнительная функциональность добавляется в функцию-обертку (вместо комментариев # сделать что-то еще...
):
def deco(fun):
def f(*args, **kwargs):
# сделать что-то еще...
result = fun(*args, **kwargs)
# сделать что-то еще...
return result
return f
А обработка функции выполняется в функции-декораторе (вместо комментария # зарегистрировать функцию...
):
def deco(fun):
# зарегистрировать функцию
return fun
Если в декоририруемую функцию не нужно добавлять дополнительную функциональность, то декоратор даже не использует функцию-обертку.
>>> Список уникальных значений
Чтобы удалить из списка повторяющиеся значения, нужно превратить его в множество и затем снова в список:
>>> # список с повторяющимися значениями
>>> a = list(2 * 'hello')
>>> a
['h', 'e', 'l', 'l', 'o', 'h', 'e', 'l', 'l', 'o']
>>>
>>> # избавимся от одинаковых элементов
>>> a = list(set(a))
>>> a
['l', 'e', 'h', 'o']
А так можно проверить, что в списке нет повторяющихся значений:
>>> if len(a) == len(set(a)):
... print('Значения в списке уникальны')
... else:
... print('Есть повторяющиеся значения')
...
Значения в списке уникальны
>>> Множества могут
Операции над множествами в Python можно выполнять с помощью методов или с помощью операторов (это справедливо не только для множеств):
>>> # объединение
>>> {1, 2, 3} | {3, 4, 5}
{1, 2, 3, 4, 5}
>>> {1, 2, 3}.union({3, 4, 5})
{1, 2, 3, 4, 5}
>>>
>>> # пересечение
>>> {1, 2, 3} & {3, 4, 5}
{3}
>>> {1, 2, 3}.intersection({3, 4, 5})
{3}
>>>
>>> # разность
>>> {1, 2, 3} - {3, 4, 5}
{1, 2}
>>> {1, 2, 3}.difference({3, 4, 5})
{1, 2}
>>>
>>> # симметрическая разность
>>> {1, 2, 3} ^ {3, 4, 5}
{1, 2, 4, 5}
>>> {1, 2, 3}.symmetric_difference({3, 4, 5})
{1, 2, 4, 5}
Комментариев нет:
Отправить комментарий