在维护的代码中经常出现大量的 if-else ,导致代码不好维护,下面的代码实现的功能是根据不同环境变量来选择执行对应的函数,后面每多一个条件判断都要加一个 elif 判断不是很优雅:
代码语言:javascript复制alt_version = os.environ.get("ATL_VERSION", "default")
if alt_version == "default":
generate_mot(pcd_dir, params, root_dir, od_mot_result)
else:
generate_mot_v2(pcd_dir, params, root_dir, od_mot_result)
改造之后的代码:
代码语言:javascript复制# 定义函数映射
function_map = {
"default": generate_mot,# 默认版本
"fangshan": generate_mot_v2
}
# 获取环境变量
alt_version = os.environ.get("ATL_VERSION", "default")
# 根据环境变量选择对应的函数执行
selected_function = function_map.get(alt_version, function_map["default"])
selected_function(pcd_dir, params, root_dir, od_mot_result)
上面是把环境变量和对应的函数做了一个字典映射,每次需要添加更多版本或者修改某个版本的函数,只需要在函数映射中进行相应的修改,而不需要修改原始的条件判断逻辑,提高了代码的可维护性。
上面优化方案是针对函数的参数都一样的,如果每个函数接收的参数不一样,则需要用到 functools.partial
代码语言:javascript复制import os
from functools import partial
def generate_mot(pcd_dir, od_mot_result):
# 实现 generate_mot 函数的具体逻辑
pass
def generate_mot_v2(params, root_dir, od_mot_result):
# 实现 generate_mot_v2 函数的具体逻辑
pass
# 定义不同版本对应的部分应用函数
generate_mot_func = partial(generate_mot, "pcd_dir", "od_mot_result")
generate_mot_v2_func = partial(generate_mot_v2, "params", "root_dir", "od_mot_result")
# 定义不同版本对应的函数映射关系
version_functions = {
"default": generate_mot_func,# 默认版本
"fangshan": generate_mot_v2_func
}
# 获取环境变量中的版本
alt_version = os.environ.get("ATL_VERSION", "default")
# 根据版本选择对应的函数,并执行
selected_function = version_functions.get(alt_version, version_functions["default"])
selected_function()
在上面例子中,使用了 functools.partial 来创建了部分应用函数 generate_mot_func 和 generate_mot_v2_func。这样,无论两个函数的参数列表是怎样的,都可以在创建部分应用函数时指定它们。然后将这些部分应用函数作为值存储在字典中,并根据版本选择相应的部分应用函数 selected_function() 执行
functools.partial 是 Python 标准库中的一个函数,用于创建一个新的可调用对象,将原函数的部分参数固定下来,形成一个新的函数。这个新函数接收的参数列表是原函数参数列表的一个子集。
假设有一个函数 func(a, b, c),可以使用 functools.partial 来创建一个新的函数,例如 new_func = partial(func, a=1),这样就创建了一个新函数 new_func,它的参数列表只包含 b 和 c,而 a 的值被固定为 1。
functools.partial 在函数式编程中非常有用,可以用来创建更具体的函数,方便地处理部分应用、柯里化等场景。这样可以减少重复代码,提高代码的可读性和可维护性。
柯里化(Currying)是函数式编程中的一种技术,它将一个多参数的函数转换为一系列单参数函数的过程。具体来说,柯里化将接受多个参数的函数转换为接受单个参数的一系列嵌套函数,每个嵌套函数接受一个参数,直到所有参数都被收集完毕后,返回最终的结果。