在 Python 中,是否认为更好的风格是:
- 根据更一般的,可能是内部使用的功能,明确定义有用的功能;或者,
- 使用部分函数应用程序来显式描述函数柯里化?
我将通过一个人为的例子来解释我的问题。
假设编写了一个函数 _sort_by_scoring,它接受两个参数:一个评分函数和一个项目列表。它根据每个项目在原始列表中的位置返回按分数排序的原始列表的副本。还提供了两个示例评分函数。
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 并返回结果。
# 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)
显然,这个意图在函数柯里化方面更好地表达了。
# Curried function definition style
import functools
identity_ordering = functools.partial(_sort_by_score, _identity_scoring)
reversed_ordering = functools.partial(_sort_by_score, _reversed_scoring)
用法(在任何一种情况下):
>>> foo = [1, 2, 3, 4, 5]
>>> identity_ordering(foo)
[1, 2, 3, 4, 5]
>>> reversed_ordering(foo)
[5, 4, 3, 2, 1]
显式函数定义风格的明显优势:
- 可以在更通用的函数之前定义有用的函数,而不会引发 NameErrors;
- 辅助函数(例如,评分函数)可以在函数定义体中定义;
- 可能更容易调试;
- 代码看起来不错,因为“显式优于隐式”。
柯里化函数定义风格的明显优势:
- 惯用地表达函数式编程的意图;
- 由于简洁,代码看起来不错。
对于定义“有用”的功能,两种风格中的哪一种更受欢迎?还有其他更惯用/ Pythonic /等的样式吗?