我有许多可重复使用的函数,都具有相同的签名(它们采用record
并返回float
)。我经常需要将函数组合成一个新函数。
假设我想要创建一个函数,该函数需要record
,对它应用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)
答案 0 :(得分:2)
假设库中有compose
,那么我更喜欢这个样式的样式。
主要原因在于它将关键值与非负值相关联并将一个函数的结果输入另一个函数。在“修改”样式中,如果您发现自己想要对某个值而不是某个函数的结果运行non_negative
,那么最终会出现non_negative(lambda x: x)(value)
之类的扭曲。而且你需要为你想要编写的每个函数编写一个单独的函数,每个函数都包含与该函数的代码混合在一起的组合逻辑。
在这个例子中,无论你采用哪种方式,负担都是微不足道的。但一般来说,如果你可以轻松地制作小的独立部分,然后将它们粘合在一起制作复合代码,那就是这样做的好方法。
答案 1 :(得分:1)
你的两个例子完全相同,除了在一种情况下你使用无点样式,而在另一种情况下你不使用。
唯一的考虑因素是您(以及阅读您的代码的人)发现最具可读性。在某些情况下,我发现点自由风格最自然;这是其中一例。