在Python中,部分函数应用程序(循环)与显式函数定义 [英] In Python, partial function application (currying) versus explicit function definition

查看:110
本文介绍了在Python中,部分函数应用程序(循环)与显式函数定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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:

  1. 有用的函数可以在更通用的函数之前定义,而不会引发NameErrors;
  2. 辅助函数(例如评分函数)可以在函数定义主体中定义;
  3. 调试起来可能更容易;
  4. 由于显式优于隐式",代码看起来不错.

咖喱函数定义风格的明显优势:

Apparent advantages of curried function definition style:

  1. 惯用的表达函数式编程的意图;
  2. 代码简洁明了.

要定义有用的"功能,应首选两种样式中的哪一种?还有其他更惯用/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:

  1. 将文档字符串分配给显式函数定义更加容易.对于partial()函数,您必须将其分配给__doc__属性,这有点难看.

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆