最近在重构代码,整理了一些关于代码—— 函 数 体 \color{red}{函数体} 函数体的简洁之道
编写短小的函数
1. 行数一般控制在一屏,大概在25~40行左右,最近流行小方法,这样的代码可读性更高,逻辑也清楚
2. 单一功能,一个函数仅实现一个功能
函数参数尽量少
在函数功能单一的前提下,最理想的参数数量为0,其次为1,再次是2,3个一般,最多不超过5个参数。
不要有冗余代码
1. 最小模块化封装,一个方法的封装,要保证这个方法是一个最小单元,以后都不可变
2. 层层封装,组装最小模块的通用性,不能以实现功能为目的
合理的扇入和扇出
何为扇入? 一个函数被多少个上级函数调用
何为扇出? 一个函数调用多少个子函数
1. 高层函数低扇入,合理扇出(一般3-4个,最大不超过7个)
2. 底层函数高扇入,低扇出,这样稳定,可重用性高
多注意导致函数复杂的其他因素
1. 引用了全局变量
2. 变量存活期过长,很多地方需要及时释放变量对应的资源
3. 函数内代码重复
圈复杂度
1. 函数入口的圈复杂度为1,从函数入口开始,每遇到一个分支则圈复杂度加1,直至函数结束。
2. 函数的平均圈复杂度控制在10以内。
函数主流程减少嵌套
建议避免超过3层的嵌套
使用卫语句——视实际情况而定
何为卫语句? 当条件表达式中只有一条是正常行为,其他都是不常见,需要作为异常处理的条件分支时,就在不合适的时候进行return。
这样做的精髓在于:强调某个条件,并告诉别人,这种条件很罕见,如果真的发生了,就要做一些必要的整理并退出。
比如代码重构前:
if a != 0:
if b != 0:
if c != 0:
pass
使用卫语句重构后:
if a == 0: return
if b == 0: return
if c == 0: return
多层 if 尝试转化成 elif
代码重构前:
if age > 10:
if age > 40:
if age > 70:
age_old += 1
else:
age_lg += 1
else:
age_mid += 1
else:
age_sm += 1
改用 elif 代码重构后:
if age > 70:
age_old += 1
elif age > 40:
age_lg += 1
elif age > 10:
age_mid += 1
else:
age_sm += 1
引入解释性变量——注意效率问题
如果判断条件(判断结果为True或False情况下)比较长,可以将判断条件以变量的形式形式提取出来,然后在判断条件中使用该变量。
代码重构前:
if os.path.basename(file_path).startswith("data") and requests_params["is_body_vars"] == 1:
pass
使用变量改造后:
exist_file = os.path.basename(file_path).startswith("data")
params_status = requests_params["is_body_vars"] == 1
if exist_file and params_status:
pass