执行高阶函数
Executing higher-order functions
我正在学习 Python 中第一个 class 函数和闭包的概念,我很想知道:
给定一个高阶函数:
def html_tag(tag):
def wrap_text(text):
print("<{0}>{1}</{0}>".format(tag, text))
return wrap_text
- 这两种执行高阶函数的方法有什么区别。
- 使用一个比另一个有什么优势吗?
- 在程序中执行高阶函数的最佳方法是什么。
1.
print_h1 = html_tag('h1')
print_h1('Test Headline')
print_h1('Another Headline')
2.
html_tag('h1')('Test Headline')
html_tag('h1')('Another Headline')
我能想到的唯一优点是,通过将 html_tag
的 return 值分配给第一个示例中的变量,您可以防止代码再次执行并且 return 每次一个新功能。而在您的第二个示例中,您直接调用 html_tag
并且每次都会产生一个新的函数引用,这将导致性能下降。
取决于您的用法,但如果您将相同的参数传递给 html_tag
,那么我会使用您的第一个示例。但是,如果您需要使用不同的标签,那么显然您将不得不使用不同的参数再次调用 html_tag
。
就函数的引用而言,这可能很重要,例如,如果您出于某种原因将函数存储在 dict
中,那么您将无法查找函数作为键,除非您保留对同一函数的引用(如第一个示例)
在你给出的例子中,结果没有区别。第二种方法效率较低,因为您多次创建等效函数,这是多余的。
当你有在运行之间保持状态的函数时,它变得更相关。
def counting_tag(tag):
counter = 0
def wrap_text(text):
nonlocal counter
counter += 1
print("<{0}>{1}. {2}</{0}>".format(tag, counter, text))
每次调用 counting_tag()
时,它都会 return 一个函数,计数器重置回 0
。
print_h1 = counting_tag('h1')
print_h1('Test Headline')
print_h1('Another Headline')
这将打印
1. Test Headline
2. Another Headline
但是如果你采用第二种方式:
counting_tag('h1')('Test Headline')
counting_tag('h1')('Another Headline')
你会得到
1. Test Headline
1. Another Headline
您拥有高阶函数的原因通常是您可以像第一个示例一样轻松生成命名辅助函数,如 print_h1
。这有两个好处:
- 您避免重复
'h1'
字符串。任何时候你必须在多个地方复制和粘贴一个字符串文字,这是由于打字错误而导致错误发生的邀请!
- 减少打字。 (这更像是不重复自己的次要好处。)
如果您打算每次都重新调用 html_tag
,就像在您的第二个示例中那样,创建高阶函数与简单地执行以下操作没有任何好处:
def html_tag(tag, text):
print("<{0}>{1}</{0}>".format(tag, text))
html_tag('h1', 'Test Headline')
html_tag('h1', 'Another Headline')
我正在学习 Python 中第一个 class 函数和闭包的概念,我很想知道:
给定一个高阶函数:
def html_tag(tag):
def wrap_text(text):
print("<{0}>{1}</{0}>".format(tag, text))
return wrap_text
- 这两种执行高阶函数的方法有什么区别。
- 使用一个比另一个有什么优势吗?
- 在程序中执行高阶函数的最佳方法是什么。
1.
print_h1 = html_tag('h1')
print_h1('Test Headline')
print_h1('Another Headline')
2.
html_tag('h1')('Test Headline')
html_tag('h1')('Another Headline')
我能想到的唯一优点是,通过将 html_tag
的 return 值分配给第一个示例中的变量,您可以防止代码再次执行并且 return 每次一个新功能。而在您的第二个示例中,您直接调用 html_tag
并且每次都会产生一个新的函数引用,这将导致性能下降。
取决于您的用法,但如果您将相同的参数传递给 html_tag
,那么我会使用您的第一个示例。但是,如果您需要使用不同的标签,那么显然您将不得不使用不同的参数再次调用 html_tag
。
就函数的引用而言,这可能很重要,例如,如果您出于某种原因将函数存储在 dict
中,那么您将无法查找函数作为键,除非您保留对同一函数的引用(如第一个示例)
在你给出的例子中,结果没有区别。第二种方法效率较低,因为您多次创建等效函数,这是多余的。
当你有在运行之间保持状态的函数时,它变得更相关。
def counting_tag(tag):
counter = 0
def wrap_text(text):
nonlocal counter
counter += 1
print("<{0}>{1}. {2}</{0}>".format(tag, counter, text))
每次调用 counting_tag()
时,它都会 return 一个函数,计数器重置回 0
。
print_h1 = counting_tag('h1')
print_h1('Test Headline')
print_h1('Another Headline')
这将打印
1. Test Headline
2. Another Headline
但是如果你采用第二种方式:
counting_tag('h1')('Test Headline')
counting_tag('h1')('Another Headline')
你会得到
1. Test Headline
1. Another Headline
您拥有高阶函数的原因通常是您可以像第一个示例一样轻松生成命名辅助函数,如 print_h1
。这有两个好处:
- 您避免重复
'h1'
字符串。任何时候你必须在多个地方复制和粘贴一个字符串文字,这是由于打字错误而导致错误发生的邀请! - 减少打字。 (这更像是不重复自己的次要好处。)
如果您打算每次都重新调用 html_tag
,就像在您的第二个示例中那样,创建高阶函数与简单地执行以下操作没有任何好处:
def html_tag(tag, text):
print("<{0}>{1}</{0}>".format(tag, text))
html_tag('h1', 'Test Headline')
html_tag('h1', 'Another Headline')