Преимущества функций высшего порядка в Python - PullRequest
1 голос
/ 04 июля 2019

Для реализации предварительно подтвержденного XML я написал следующий код

def prettify_by_response(response, prettify_func):
    root = ET.fromstring(response.content)
    return prettify_func(root)

def prettify_by_str(xml_str, prettify_func):
    root = ET.fromstring(xml_str)
    return prettify_func(root)

def make_pretty_xml(root):
    rough_string = ET.tostring(root, "utf-8")
    reparsed = minidom.parseString(rough_string)
    xml = reparsed.toprettyxml(indent="\t")
    return xml

def prettify(response):
    if isinstance(response, str) or isinstance(response, bytes):
        return prettify_by_str(response, make_pretty_xml)
    else:
        return prettify_by_response(response, make_pretty_xml)

В функциях prettify_by_response и prettify_by_str я передаю функцию make_pretty_xml в качестве аргумента

Вместо передачи функции в качестве аргумента, яможно просто вызвать эту функцию. Например,

def prettify_by_str(xml_str, prettify_func):
   root = ET.fromstring(xml_str)
   return make_pretty_xml(root)

Одним из преимуществ передачи функции в качестве аргумента этой функции по сравнению с непосредственным вызовом этой функции является то, что эта функция не тесно связана с функцией make_pretty_xml.

Какие были бы другие преимущества или я добавляю дополнительную сложность?

1 Ответ

0 голосов
/ 04 июля 2019

Это кажется очень открытым для предвзятых ответов. Я постараюсь быть беспристрастным, но не могу дать никаких обещаний.

Во-первых, функции высокого порядка - это функции, которые получают и / или возвращают функции.Преимущества сомнительны, я попытаюсь перечислить использование HoF и выяснить преимущества и недостатки каждого из них

Обратные вызовы

Обратные вызовы стали решением проблемы блокировки вызовов.Мне нужно, чтобы B произошло после A, поэтому я вызываю что-то, что блокирует A, а затем вызываю B.Эта природа приводит к таким вопросам, как Хм, моя система тратит много времени на ожидание того, что произойдет.Что делать, если вместо ожидания я могу получить то, что нужно сделать, в качестве аргумента. Как что-то новое в технологии, которое еще не масштабировалось, покажется хорошей идеей, пока не масштабируется.

Обратные вызовы очень распространенына систему событий.Если вы каждый код в javascript знаете, о чем я говорю.

Абстракция алгоритма

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

Присоединение поведения к другим функциям

Идея здесь - взять функцию в качестве аргумента и вернуть функцию, которая выполняет именно то, чтоФункция аргумента имеет, плюс, некоторое прикрепленное поведение.И именно здесь (я думаю) HoF действительно сияет.

Декораторы Python являются прекрасным примером.Они принимают функцию в качестве аргумента и возвращают другую функцию.Эта функция прикреплена к тому же идентификатору первой функции

@foo
def bar(*args):
   ...

совпадает с

def bar(*args):
    ...
bar = foo(bar)

Теперь отразите на этом коде

from functools import lru_cache

@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

fib - это просто функция Фибоначчи.Он рассчитывает число Фибоначчи до n.Теперь lru_cache добавьте новое поведение кеширования результатов для уже ранее вычисленных значений.Логика внутри функции fib не испорчена логикой кеша LRU.Какая прекрасная часть абстракции у нас здесь.

Аппликативный стиль программирования или бессмысленное программирование

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

Как примечание: это не очень распространенный стиль в питоне.

for i in it:
    func(i)
from functools import partial

mapped_it = map(func, it)

Во втором примере мы удалили переменную i.Это обычное дело при разборе мира.Как еще один побочный узел, функция map ленива в Python, поэтому второй пример не действует, пока вы не выполните итерации по mapped_it

Ваш случай

В вашем случае вывозвращая значение обратного вызова.На самом деле вам не нужен обратный вызов, вы можете просто выстроить вызовы, как вы делали, и для этого случая вам не нужен HoF.

Надеюсь, это поможет, и кто-то может показать лучшие примеры аппликативного стиля:)

С уважением

...