Автор оригинала: Pankaj Kumar.
Одна из самой большой мощности, которую демонстрирует Python, является предоставление инструментов для записи повторно используемого кода. В этом уроке мы узнаем о модуле Python Functools, который делает пишущий многоразовый код простой и очень пригодным для удовлетворения.
Модуль Python Funccools
Python Functools
Модуль предоставляет нам различные инструменты, которые позволяют нам писать для писать многоразовый код. Некоторые из них:
- Частичные функции
- Обновление частичных обертков
- Общий заказа
Начнем наш пост с краткосрочным и информативным обсуждением частичных функций.
Что такое частичные функции?
Python Functools Частичные функции используются для:
- Реплицируйте существующие функции с некоторыми аргументами, уже переданными.
- Создание новой версии функции в хорошо документированном виде.
Частичные функции с использованием Funccools
Точки, которые мы заявили выше, могут быть хорошо поняты с некоторыми примерами. Давайте изучим их сейчас.
Предположим, у вас есть функция под названием множитель
который просто умножает два числа. Его определение выглядит как:
def multiplier(x, y): return x * y
Теперь, что если мы хотим сделать некоторые выделенные функции для двойного или тройного номера? Нам придется определить новые функции как:
def multiplier(x, y): return x * y def doubleIt(x): return multiplier(x, 2) def tripleIt(x): return multiplier(x, 3)
Ну, это было легко, но что происходит, когда нам нужно 1000 таких функций? Здесь мы можем использовать частичные функции:
from functools import partial def multiplier(x, y): return x * y double = partial(multiplier, y=2) triple = partial(multiplier, y=3) print('Double of 2 is {}'.format(double(5)))
Ну, это было намного короче, не так ли? Вывод примера остается незатронутым как:
from functools import partial def multiplier(x, y): return x * y multiplier_partials = [] for i in range (1, 11): function = partial(multiplier, i) multiplier_partials.append(function) print('Product of 1 and 2 is {}'.format(multiplier_partials[0](2))) print('Product of 3 and 2 is {}'.format(multiplier_partials[2](2))) print('Product of 9 and 2 is {}'.format(multiplier_partials[8](2)))
На этот раз мы собрали больше функций в списке и назвали их. Вывод будет:
Частичные функции самодоступны
Несмотря на то, что частичные функции могут рассматриваться как полностью независимые функции, они сами никогда не теряют память о функции, которая их способствует.
Это может быть доказано из DOC Meta-Data, которые они держат:
from functools import partial def multiplier(x, y): return x * y double = partial(multiplier, y=2) triple = partial(multiplier, y=3) print('Function powering double is {}'.format(double.func)) print('Default keywords for double is {}'.format(double.keywords))
Вывод будет: первый вызов дает имя функции со своим адресом памяти.
Тестирование частичных функций в Functools
Просто проверить частичную функцию. Мы даже можем проверить его документацию. Давайте посмотрим, как это сделано:
from functools import partial def multiplier(x, y): return x * y double = partial(multiplier, y=2) triple = partial(multiplier, y=3) assert double.func == multiplier assert double.keywords == {'y': 2}
Когда вы запускаете этот скрипт, вы не увидите никакого вывода, поскольку утверждения дают только выходную ошибку при провайдере. Если они пройдут, они молча продолжают выполнение кода.
Обновить частичную функцию метаданных с помощью functool.update_wrapper ()
С модулем Functools мы можем обновить метаданные функции с помощью обертков. Давайте посмотрим на примерный фрагмент кода, чтобы уточнить, как это сделано:
import functools def multiplier(x, y): """Multiplier doc string.""" return x * y def show_details(name, function): """Details callable object.""" print('Name: {}'.format(name)) print('\tObject: {}'.format(function)) try: print('\t__name__: {}'.format(function.__name__)) except AttributeError: print('\t__name__: {}'.format('__no name__')) print('\t__doc__ {}'.format(repr(function.__doc__))) return double = functools.partial(multiplier, y=2) show_details('raw wrapper', double) print('Updating wrapper:') print('\tassign: {}'.format(functools.WRAPPER_ASSIGNMENTS)) print('\tupdate: {}'.format(functools.WRAPPER_UPDATES)) functools.update_wrapper(double, multiplier) show_details('updated wrapper', double)
Выход этого сценария будет: Перед обновлением обертки частичная функция не имела никаких данных о его имени и правильной строке DOC, но update_wrapper ()
Функция изменила это.
Всего заказа с помощью функции
Модуль Functools также предоставляет способ обеспечить автоматические функции сравнения. Существует 2 состояния, которые необходимо выполнить для достижения результатов:
- Определение по меньшей мере одной функции сравнения является обязательным, как
Ле
,LT
,GT
илиGE
Отказ - Определение
EQ
Функция обязательна.
Итак, это то, что мы будем делать:
from functools import total_ordering @total_ordering class Number: def __init__(self, value): self.value = value def __lt__(self, other): return self.value < other.value def __eq__(self, other): return self.value == other.value print(Number(1) < Number(2)) print(Number(10) > Number(21)) print(Number(10) <= Number(2)) print(Number(10) >= Number(20)) print(Number(2) <= Number(2)) print(Number(2) >= Number(2)) print(Number(2) == Number(2)) print(Number(2) == Number(3))
Выход этого скрипта будет: это было на самом деле было легко понять, так как он позволил нам удалить избыточный код в определении нашего класса.
В этом уроке мы узнали о различных способах, через которые мы можем улучшить повторное использование кода с Functools
Модуль в Python.
Ссылка: API док