考虑如下定义的Python函数line
:
def line(m, b):
def inner_function(x):
return m * x + b
return inner_function
此函数的属性是,对于任何浮点数m
和b
,对象line(m, b)
是Python函数,并且在浮点数{{ 1}},则返回浮点数line(m, b)
。浮点x
可以解释为在点line(m, b)(x)
处具有斜率line(m, b)(x)
和y截距m
的线的值。这是一种编写“取决于参数” b
和x
的Python函数的方法。
m
相同的功能的函数?答案 0 :(得分: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参考解释器中),并且如您所见,它们也比较冗长,所以我通常建议闭包除非您的需求需要更大的类实例灵活性/功能。
答案 1 :(得分:3)
我支持@ShaddowRanger的回答。但是使用partial
是另一种不错的方法。
import functools
def f(m, b, x):
return m * x + b
line = functools.partial(f, 2, 3)
line(5)
=> 13
值得指出的一件事是lambda
对象和OP的inner_function
不可腌制,而这里的line
以及@ShaddowRanger的Line
对象是的,这使它们更有用。
答案 2 :(得分:1)
这有点短:
def line(m,b):
return lambda x: m*x+b;