在Python中,部分函数应用程序(循环)与显式函数定义 [英] In Python, partial function application (currying) versus explicit function definition
问题描述
在Python中,以下方式是否被认为是更好的样式:
In Python, is it considered better style to:
- 根据更一般的功能(可能是内部使用的功能)明确定义有用的功能;或者,
- 使用部分函数应用程序来显式描述函数currying?
我将通过一个人为的例子来说明我的问题.
I will explain my question by way of a contrived example.
假设一个人编写了一个函数_sort_by_scoring,它带有两个参数:一个评分函数和一个项目列表.它返回原始列表的副本,该副本根据每个项目在原始列表中的位置按分数排序.还提供了两个示例评分功能.
Suppose one writes a function, _sort_by_scoring, that takes two arguments: a scoring function and a list of items. It returns a copy of the original list sorted by scores based on each item's position within the original list. Two example scoring functions are also provided.
def _sort_by_score(scoring, items_list):
unsorted_scored_list = [(scoring(len(items_list), item_position), item) for item_position, item in enumerate(items_list)]
sorted_list = [item for score, item in sorted(unsorted_scored_list)]
return sorted_list
def _identity_scoring(items_list_size, item_position):
return item_position
def _reversed_scoring(items_list_size, item_position):
return items_list_size - item_position
从未直接调用_sort_by_score函数;相反,它由其他单参数函数调用,这些函数将计分函数及其唯一参数(项目列表)传递给_sort_by_scoring并返回结果.
The function _sort_by_score is never called directly; instead, it is called by other single-argument functions that pass a scoring function and their lone argument (a list of items) to _sort_by_scoring and return the result.
# Explicit function definition style
def identity_ordering(items_list):
return _sort_by_score(_identity_scoring, items_list)
def reversed_ordering(items_list):
return _sort_by_score(_reversed_scoring, items_list)
很明显,这种意图可以用函数递归来更好地表达.
Obviously, this intent is better expressed in terms of function currying.
# Curried function definition style
import functools
identity_ordering = functools.partial(_sort_by_score, _identity_scoring)
reversed_ordering = functools.partial(_sort_by_score, _reversed_scoring)
用法(在任何一种情况下):
Usage (in either case):
>>> foo = [1, 2, 3, 4, 5]
>>> identity_ordering(foo)
[1, 2, 3, 4, 5]
>>> reversed_ordering(foo)
[5, 4, 3, 2, 1]
显式函数定义样式的明显优点:
Apparent advantages of the explicit function definition style:
- 有用的函数可以在更通用的函数之前定义,而不会引发NameErrors;
- 辅助函数(例如评分函数)可以在函数定义主体中定义;
- 调试起来可能更容易;
- 由于显式优于隐式",代码看起来不错.
咖喱函数定义风格的明显优势:
Apparent advantages of curried function definition style:
- 惯用的表达函数式编程的意图;
- 代码简洁明了.
要定义有用的"功能,应首选两种样式中的哪一种?还有其他更惯用/Pythonic/etc的样式吗?
For defining "useful" functions, which of the two styles is preferred? Are there other styles that are more idiomatic/Pythonic/etc.?
推荐答案
如果您希望将咖喱函数作为公共接口的一部分,请使用显式函数定义.这样做还有其他优点:
If you want to have the curried functions as part of a public interface, use explicit function definitions. This has the following additional advantages:
-
将文档字符串分配给显式函数定义更加容易.对于
partial()
函数,您必须将其分配给__doc__
属性,这有点难看.
It is easier to assign a docstring to an explicit function definition. For
partial()
functions, you would have to assign to the__doc__
attribute, which is somewhat ugly.
在浏览模块源代码时,更容易浏览实函数定义.
Real function definitions are easier to skim when browsing the module source.
我将以与lambda表达式类似的方式使用functools.partial()
,即用于本地需要的抛弃式函数.
I would use functools.partial()
in a similar way to lambda expressions, i.e. for locally needed throw-away functions.
在您的特定示例中,我可能都不会使用,删除下划线并致电
In your particular example, I'd probably use neither, drop the leading underscores and call
sort_by_score(identity_scoring, foo)
对我来说,这似乎是最明确的.
which seems the most explicit to me.
这篇关于在Python中,部分函数应用程序(循环)与显式函数定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!