面试题答案
一键面试设计思路
- 参数校验:为每个插件的
run
函数定义一个参数规范,例如使用typing
模块来明确参数的类型和是否必需。 - 默认值设置:在参数规范中同时定义参数的默认值。
- 错误处理:使用
try - except
块捕获在调用run
函数过程中可能出现的异常,如参数类型错误等,并进行适当处理。 - 扩展性:将参数规范和插件模块的映射关系进行抽象,方便后续添加新的插件模块。
关键部分代码示例
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}')