Ade*_*mro 16 python functional-programming currying partial-application
在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
Run Code Online (Sandbox Code Playgroud)
函数_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)
Run Code Online (Sandbox Code Playgroud)
显然,这个意图在函数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)
Run Code Online (Sandbox Code Playgroud)
用法(在任何一种情况下):
>>> foo = [1, 2, 3, 4, 5]
>>> identity_ordering(foo)
[1, 2, 3, 4, 5]
>>> reversed_ordering(foo)
[5, 4, 3, 2, 1]
Run Code Online (Sandbox Code Playgroud)
显式函数定义样式的明显优势:
curried函数定义风格的明显优势:
为了定义"有用"功能,首选哪两种样式?还有其他风格更惯用/ Pythonic /等?
Sve*_*ach 13
如果要将curried函数作为公共接口的一部分,请使用显式函数定义.这具有以下额外优势:
将docstring分配给显式函数定义更容易.对于partial()函数,您必须分配__doc__属性,这有点难看.
浏览模块源时,实际函数定义更容易浏览.
我将以functools.partial()类似于lambda表达式的方式使用,即用于本地需要的丢弃函数.
在您的特定示例中,我可能不使用,删除前导下划线并调用
sort_by_score(identity_scoring, foo)
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎最明确.