MST

星途 面试题库

面试题:Python **kwargs 在复杂系统架构中的优化应用

在一个大型 Python 项目中,有一系列的插件模块,每个插件模块都有一个 `run` 函数,这些 `run` 函数接受不同数量和类型的参数。现在需要设计一个统一的调度函数 `dispatch` ,它使用 **kwargs 来灵活调用各个插件模块的 `run` 函数,同时要考虑到参数的校验、默认值设置以及错误处理机制,以确保整个系统的稳定性和扩展性。请详细描述你的设计思路,并给出关键部分的代码示例。
18.6万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 参数校验:为每个插件的 run 函数定义一个参数规范,例如使用 typing 模块来明确参数的类型和是否必需。
  2. 默认值设置:在参数规范中同时定义参数的默认值。
  3. 错误处理:使用 try - except 块捕获在调用 run 函数过程中可能出现的异常,如参数类型错误等,并进行适当处理。
  4. 扩展性:将参数规范和插件模块的映射关系进行抽象,方便后续添加新的插件模块。

关键部分代码示例

from typing import Dict, Any, Callable, Optional
import inspect


# 假设这是插件模块1
def plugin1_run(a: int, b: str = 'default') -> None:
    print(f'Plugin1 running with a={a}, b={b}')


# 假设这是插件模块2
def plugin2_run(c: float, d: Optional[int] = None) -> None:
    print(f'Plugin2 running with c={c}, d={d}')


# 参数规范
param_specs: Dict[str, Dict[str, Any]] = {
    'plugin1': {
        'a': {'type': int,'required': True},
        'b': {'type': str,'required': False, 'default': 'default'}
    },
    'plugin2': {
        'c': {'type': float,'required': True},
        'd': {'type': int,'required': False, 'default': None}
    }
}


# 插件模块映射
plugin_modules: Dict[str, Callable] = {
    'plugin1': plugin1_run,
    'plugin2': plugin2_run
}


def dispatch(plugin_name: str, **kwargs) -> None:
    if plugin_name not in plugin_modules:
        raise ValueError(f'Plugin {plugin_name} not found')

    spec = param_specs[plugin_name]
    func = plugin_modules[plugin_name]

    # 检查参数并设置默认值
    call_kwargs = {}
    for param_name, param_info in spec.items():
        if param_name not in kwargs:
            if param_info['required']:
                raise ValueError(f'Parameter {param_name} is required for plugin {plugin_name}')
            call_kwargs[param_name] = param_info['default']
        else:
            value = kwargs[param_name]
            if not isinstance(value, param_info['type']):
                raise TypeError(f'Parameter {param_name} should be of type {param_info["type"]}')
            call_kwargs[param_name] = value

    try:
        func(**call_kwargs)
    except Exception as e:
        print(f'Error occurred while running plugin {plugin_name}: {e}')


你可以使用以下方式调用 dispatch 函数:

# 调用示例
try:
    dispatch('plugin1', a=123)
    dispatch('plugin2', c=3.14, d=567)
except (ValueError, TypeError) as e:
    print(f'Error in dispatch: {e}')