Автор оригинала: 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 док