首页 > 解决方案 > 高阶函数和类有什么区别?

问题描述

我正在学习函数式编程的基础知识,最终遇到了高阶函数的概念。我在Corey Schafer的这个视频中看到了一个示例(从 11:00 开始),它显示了一个 Python 函数,可以将消息包装在任意 HTML 标记中:

def html_tag(tag):
    def wrap_text(msg):
        print('<{0}>{1}</{0}>'.format(tag, msg))

    return wrap_text

print_h1 = html_tag('h1')
print_h1('Test Headline!')
print_h1('Another Headline!')

print_p = html_tag('p')
print_p('Test Paragraph!')

输出:

<h1>Test Headline!</h1>
<h1>Another Headline!</h1>
<p>Test Paragraph!</p>

我知道它为您提供了为不同目的(在此示例中为不同的标签)重新使用相同功能的灵活性。但是您也可以使用 Python classes获得相同的结果:

class HTML_tag:
    def __init__(self, tag):
        self.tag = tag
    
    def wrap_text(self, msg):
        print('<{0}>{1}</{0}>'.format(self.tag, msg))

print_h1 = HTML_tag('h1')
print_h1.wrap_text('Test Headline!')
print_h1.wrap_text('Another Headline!')

print_p = HTML_tag('p')
print_p.wrap_text('Test Paragraph!')

输出:

<h1>Test Headline!</h1>
<h1>Another Headline!</h1>
<p>Test Paragraph!</p>

高阶函数方法确实看起来更干净,但除了美观之外,还有什么其他原因我可能更喜欢高阶函数而不是类?例如,关于诸如

标签: pythonfunctional-programminghigher-order-functions

解决方案


高阶函数采用和/或返回函数。让我们看看这两种情况。

将函数作为参数

在这里,HOF 绝对是必经之路。类版本相当于一个带有额外步骤的 HOF。对于类版本,您需要预先协商函数可调用的密钥。它实际上是您要完成的内容的无用包装。

霍夫

def my_map(fn, arr):
  result = []
  for a in arr:
    result.append(fn(a))
  return result

my_map(lambda a: a + 1, [1, 2, 3]) # [2, 3, 4]

类版本

def my_map(inst, arr):
  result = []
  for a in arr:
    result.append(inst.fn(a))
  return result

class my_mapper:
  def fn(self, a):
    return a + 1

my_map(my_mapper(), [1, 2, 3]) # [2, 3, 4]

返回一个函数

在这里的两个版本中,我们正在做的是创建一些 value 的封装a,以及一个在它上面工作的函数。

我认为,如果您希望在某些数据上定义多个函数,当封装的数据可以更改(您正在编码状态机),或者当您希望操作特定于您的类时,我认为一个类通常很有用(即您的班级的用户需要知道在班级上定义的操作)。

当我所做的相当于部分应用程序时,我会使用一个返回函数的函数(我有一个带有多个参数的函数,我想预先应用一些参数,比如“add”)。我也会functools.partial用来做这个。

def adder(a):
  return lambda b: a + b
class adder_class:
  def __init__(self, a):
    self.a = a

  def add(self, b):
    return a + b

最终,无论是最好使用 HOF 还是类,都将在上下文中变得清晰。


推荐阅读