python - 高阶函数和类有什么区别?
问题描述
我正在学习函数式编程的基础知识,最终遇到了高阶函数的概念。我在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>
高阶函数方法确实看起来更干净,但除了美观之外,还有什么其他原因我可能更喜欢高阶函数而不是类?例如,关于诸如
- 表现
- 记忆
- ...
解决方案
高阶函数采用和/或返回函数。让我们看看这两种情况。
将函数作为参数
在这里,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 还是类,都将在上下文中变得清晰。
推荐阅读
- php - 将字符串格式的函数转换为计算
- spring-boot - 无法在外部 tomcat 上部署 Spring Boot 应用程序
- github - 范围有限的个人访问令牌可以与其他用户共享吗?
- node.js - 通过 socket.io 连接以响应本机和风帆
- amazon-web-services - 如何在 Terraformer 中使用过滤器来导入 AWS Lambda 函数
- angular - Angular Froala - 将图像上传到 Firebase
- regex - 不匹配 ( 和 ),但匹配 '(' 和 ')' 的正则表达式
- python - 在 python 文件中导入已导入文件
- sequelize.js - Sequelize:检索实体时是否可以包含多个级别的关联
- redux - 如何在 Redux 中使用共享 reducer