2

line考虑如下定义的 Python 函数:

def line(m, b):
    def inner_function(x):
        return m * x + b
    return inner_function

此函数具有对于任何 floatm和的属性b,该对象line(m, b)是 Python 函数,当line(m, b)在 float 上调用时x,它返回一个 float line(m, b)(x)。浮点数line(m, b)(x)可以解释为在点 具有斜率m和 y 截距的线b的值x。这是编写“取决于参数”的 Python 函数的一种方法,m并且b.

  1. 这种编写依赖于某些参数的 Python 函数的方法是否有特殊名称?
  2. 是否有更 Pythonic 和/或计算效率更高的方法来编写与上述功能相同的函数line
4

3 回答 3

6

这称为闭包,它是一种非常合理的编写方式,也是最有效的方法之一(无论如何在 CPython 参考解释器中)。

我知道的唯一其他常见模式是 C++ 的仿函数的等价物,其中一个类将状态作为属性,并将附加参数传递给__call__,例如以匹配您的情况:

class Line:
    def __init__(self, m, b):
        self.m = m
        self.b = b
    def __call__(self, x):
        return self.m * x + self.b

它的使用方式相同,要么创建/存储实例并重用它,要么如您的示例中那样,创建它,使用它一次,然后将其丢弃(Line(m, b)(x))。函子虽然比闭包慢(因为属性访问比从嵌套范围读取更昂贵,至少在 CPython 参考解释器中),而且如您所见,它们也更冗长,所以我通常推荐闭包除非您的需求需要类实例更大的灵活性/功能。

于 2019-12-11T20:02:38.793 回答
3

我支持@ShaddowRanger 的回答。但是使用partial是另一种不错的方法。

import functools
def f(m, b, x):
    return m * x + b
line = functools.partial(f, 2, 3)
line(5)
=> 13

值得指出的一件事是lambda对象和 OPinner_function是不可腌制的,而line在这里,以及 @ShaddowRanger 的Line对象是,这使得它们更有用一点。

于 2019-12-11T20:05:38.980 回答
1

这有点短:

def line(m,b):
    return lambda x: m*x+b;
于 2019-12-11T20:06:30.547 回答