Python 函数组合与作用于另一个函数的函数
我有许多可重用的函数,它们都具有相同的签名(它们接受Python 函数组合与作用于另一个函数的函数,python,functional-programming,python-3.x,function-composition,Python,Functional Programming,Python 3.x,Function Composition,我有许多可重用的函数,它们都具有相同的签名(它们接受记录并返回浮点)。我经常需要将函数组合成一个新函数 假设我想创建一个函数,它接受一条记录,对其应用f,如果结果为负,则将其转换为零。我有两种方法:合成和功能修改。每种方法的优缺点是什么 组成: def non_negative(value): return max(0, value) g = compose(non_negative, f) # from functional module by Collin Winter def
记录
并返回浮点
)。我经常需要将函数组合成一个新函数
假设我想创建一个函数,它接受一条记录
,对其应用f
,如果结果为负,则将其转换为零。我有两种方法:合成和功能修改。每种方法的优缺点是什么
组成:
def non_negative(value):
return max(0, value)
g = compose(non_negative, f)
# from functional module by Collin Winter
def compose(func_1, func_2, unpack=False):
"""
compose(func_1, func_2, unpack=False) -> function
The function returned by compose is a composition of func_1 and func_2.
That is, compose(func_1, func_2)(5) == func_1(func_2(5))
"""
if not callable(func_1):
raise TypeError("First argument to compose must be callable")
if not callable(func_2):
raise TypeError("Second argument to compose must be callable")
if unpack:
def composition(*args, **kwargs):
return func_1(*func_2(*args, **kwargs))
else:
def composition(*args, **kwargs):
return func_1(func_2(*args, **kwargs))
return composition
修改:
def non_negative(func):
def new_func(record):
return max(0, func(record))
return new_func
g = non_negative(f)
您的两个示例完全相同,只是在一种情况下使用无点样式,而在另一种情况下不使用
唯一需要考虑的是您(以及阅读您的代码的人)认为哪一个最具可读性。在某些情况下,我觉得无点风格最自然;这就是其中一种情况。您的两个示例完全相同,只是在一种情况下使用了无点样式,而在另一种情况下不使用
唯一需要考虑的是您(以及阅读您的代码的人)认为哪一个最具可读性。在某些情况下,我觉得无点风格最自然;这就是其中的一种情况。假设库中有可用的
compose
,那么我更喜欢这种样式
主要原因是它分离出了将值钳制为非负值以及将一个函数的结果传递给另一个函数的关注点。在“修改”风格中,如果您发现自己想要对一个值而不是函数的结果运行非负的
,那么最终会出现类似非负(λx:x)(值)
的扭曲。您需要为您可能要编写的每个函数编写一个单独的函数,其中每个函数都包含与该函数的代码混合的编写逻辑
在本例中,无论您采用何种方式,负担都是微不足道的。但是,一般来说,如果很容易制作出独立的小片段,然后将它们粘在一起生成复合代码,那么这是一个很好的方法。假设库中有
compose
,那么我更喜欢这种样式
主要原因是它分离出了将值钳制为非负值以及将一个函数的结果传递给另一个函数的关注点。在“修改”风格中,如果您发现自己想要对一个值而不是函数的结果运行非负的
,那么最终会出现类似非负(λx:x)(值)
的扭曲。您需要为您可能要编写的每个函数编写一个单独的函数,其中每个函数都包含与该函数的代码混合的编写逻辑
在本例中,无论您采用何种方式,负担都是微不足道的。但一般来说,如果很容易制作出独立的小片段,然后将它们粘在一起生成复合代码,那么这是一个很好的方法。您所做的是专门编写非负的代码。@dad。谢谢。。我不熟悉函数式编程,所以我不知道有一个术语来表示它。你能给我介绍一些讨论这个问题的介绍性材料吗?函数专门化是关于函数的一个或多个参数。它可以通过一个程序来完成,默认情况下,这个程序就是这个术语所暗示的,但是它也可以通过手工来完成,就像你所做的那样。第二个示例中的代码,
non_negative
是针对第一个代码示例中的non_negative
函数的compose
的专门版本。严格来说,您的修改示例不起作用,因为您没有返回new_func
,因此,g
最终变成了None
@Ben:oops,修正了@我明白了。这种专门化似乎会限制非负数的可重用性,因为它被限制为一个签名。您所做的是专门化撰写有关非负数的内容。@DanD。谢谢。。我不熟悉函数式编程,所以我不知道有一个术语来表示它。你能给我介绍一些讨论这个问题的介绍性材料吗?函数专门化是关于函数的一个或多个参数。它可以通过一个程序来完成,默认情况下,这个程序就是这个术语所暗示的,但是它也可以通过手工来完成,就像你所做的那样。第二个示例中的代码,non_negative
是针对第一个代码示例中的non_negative
函数的compose
的专门版本。严格来说,您的修改示例不起作用,因为您没有返回new_func
,因此,g
最终变成了None
@Ben:oops,修正了@我明白了。这种专门化似乎会限制非负的可重用性,因为它被限制为一个签名。我不知道“无点”是什么意思。当然,答案也是:。我能问你为什么在这种情况下,你会觉得无点风格更自然?它确实需要更多的输入…@max:假设compose是一个库函数,它需要的时间就更少了。compose
是一个库函数;但是我比较了非负(f)
和组合(非负,f)
@max:是的,但是装饰风格更难理解。我不知道“无点”是什么意思。当然,答案也是:。我能问你为什么在这种情况下,你会觉得无点风格更自然?它确实需要更多的输入…@max:假设compose是一个库函数,它需要的时间就更少了。compose
是一个库函数;但是我比较了非负(f)
和组合(非负,f)
@max:是的,但是装饰风格更难理解。