面试题答案
一键面试可能出现的问题
- 性能问题:
- 可变默认参数:如果函数使用可变对象(如列表、字典)作为默认参数,每次函数调用时若未传入新值,会使用同一个默认对象实例。例如,若在函数内部对该默认对象进行修改,后续调用时默认对象的状态已改变,可能导致非预期结果且难以调试,同时也会造成不必要的内存开销。
- 复杂计算作为默认值:若默认值是通过复杂计算得到,每次函数调用都会重新计算,导致性能下降。
- 维护性问题:
- 难以理解和修改:多个模块相互调用带有默认值的函数,默认值分散在不同函数定义处,若要修改默认值,需要在多个地方查找和修改,容易遗漏且难以统一维护。
- 版本兼容性:项目演进过程中,若默认值改变,可能影响到依赖该函数的其他模块,导致兼容性问题。
优化方案
- 解决可变默认参数问题:
- 使用
None
作为默认值,在函数内部判断并初始化可变对象。例如:
- 使用
def my_function(param= None):
if param is None:
param = []
# 函数其他逻辑
return param
- 处理复杂计算默认值:
- 将复杂计算逻辑提取到单独函数中,使用
functools.lru_cache
进行缓存(如果计算结果不依赖于外部可变状态)。例如:
- 将复杂计算逻辑提取到单独函数中,使用
import functools
@functools.lru_cache(maxsize = None)
def complex_calculation():
# 复杂计算逻辑
return result
def my_function_with_complex_default(param = complex_calculation()):
# 函数其他逻辑
return param
- 集中管理默认值:
- 在一个单独的配置模块中定义所有函数的默认值,这样在需要修改默认值时,只需在一个地方修改。例如:
# config.py
DEFAULT_LIST = []
DEFAULT_DICT = {}
DEFAULT_COMPLEX_RESULT = complex_calculation()
# other_module.py
from config import DEFAULT_LIST, DEFAULT_DICT, DEFAULT_COMPLEX_RESULT
def my_function1(param = DEFAULT_LIST):
# 函数逻辑
return param
def my_function2(param = DEFAULT_DICT):
# 函数逻辑
return param
def my_function3(param = DEFAULT_COMPLEX_RESULT):
# 函数逻辑
return param
- 提高代码健壮性和可扩展性:
- 添加类型检查:使用
typing
模块进行类型提示,在函数入口处检查参数类型,确保传入参数与默认值类型一致。例如:
- 添加类型检查:使用
from typing import List
def my_function(param: List[int] = []):
if not isinstance(param, list) or param and not all(isinstance(i, int) for i in param):
raise ValueError('param should be a list of integers')
# 函数其他逻辑
return param
- 设计默认值时考虑灵活性:例如,对于一些与业务逻辑相关的默认值,可以通过配置文件或者环境变量来动态调整,这样在不同部署环境下可以灵活设置默认值而无需修改代码。
通过这些优化方案,可以有效解决默认值在性能和维护性上的问题,提高代码的健壮性和可扩展性。