python - Python 中高阶函数的优点

标签 python functional-programming higher-order-functions

为了实现美化的 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 函数不紧密耦合。

还有什么其他优势或者我是否会增加额外的复杂性?

最佳答案

这似乎很容易出现有偏见的答案,我会尽力保持公正,但我无法做出任何 promise 。

首先,高阶函数是接收和/或返回函数的函数。优点值得商榷,我将尝试列举HoF的用法并阐明每种方法的优缺点

回调

回调是一种阻止调用的解决方案。我需要 BA 之后发生,所以我调用了在 A 上阻塞的东西,然后调用 B。这自然会导致一些问题,例如,嗯,我的系统浪费了大量时间来等待事情发生。如果我不用等待就能得到我需要做的事情作为参数传递,那会怎么样?因为任何尚未扩展的新技术在扩展之前似乎都是一个好主意。

回调在事件系统中非常常见。如果您熟悉 JavaScript 中的每段代码,您就会知道我在说什么。

算法抽象

一些设计,主要是行为设计​​,可以利用 HoF 在运行时选择某种算法。您可以拥有一个高级算法来接收处理低级内容的函数。这导致更多的抽象代码重用和可移植代码。在这里,可移植意味着您可以编写代码来处理新的低级别,而无需更改高级级别。这与 HoF 无关,但可以利用它们提供很大帮助。

将行为附加到另一个函数

这里的想法是将函数作为参数并返回一个函数,该函数完全执行参数函数的操作,再加上一些附加行为。 (我认为)这就是 HoF 真正闪光的地方。

Python 装饰器就是一个完美的例子。它们将一个函数作为参数并返回另一个函数。该函数附加到第一个函数的相同标识符

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

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

现在,反射(reflection)一下这段代码

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 缓存逻辑的污染。我们这里有多么美丽的抽象。

应用式编程或无点编程

这里的想法是删除变量或点并结合函数应用来表达算法。我确信在这个主题上有很多比我更好的人。

顺便说一句,这在 python 中不是很常见的样式。

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

mapped_it = map(func, it)

在第二个示例中,我们删除了 i 变量。这在解析世界中很常见。作为另一个侧节点,map 函数在 python 中是惰性的,因此第二个示例只有在迭代 mapped_it

时才会生效。

您的案例

在您的情况下,您将返回回调调用的值。事实上,您不需要回调,您只需像以前那样排列调用即可,并且对于这种情况您不需要 HoF。

我希望这会有所帮助,并且有人可以展示更好的应用风格示例:)

问候

关于python - Python 中高阶函数的优点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56879453/

相关文章:

function - 如何编写一个接受函数片段的函数?

python - Python 中 set.discard 和 set.remove 方法之间的运行时差异?

python - 重构数据帧中列乘法中的错误 'code smell'

python - 树遍历,递归比python中的迭代更快?

haskell - 原始递归函数

lambda - lambda 是一种高阶函数吗?

functional-programming - "Value Restriction"实际上意味着没有高阶函数式编程吗?

python - 无法消除 django-cms 产生的警告

haskell - 为我的数据类型实现 Functor 时出错

functional-programming - 具有所有中间值的列表的总和