如何在Python中实现类C++模板函数以适配Advent of Code任务?
Advent of Code 代码架构优化问题
我近期在完成大量Advent of Code任务时,给自己设定了严格遵循最佳实践的挑战,包括使用类型提示(typing)、保证代码DRY(Don't Repeat Yourself)、分离数据结构与逻辑,但遇到了架构设计上的问题:
需要实现的代码分为三类,且每个问题(共25个)对应一套:
- 25种数据类型:命名为
Data_i(i为1到25的整数) - 数据加载方法:每个
Data_i对应一个load_data_i函数,负责从文件解析生成Data_i类型实例 - 任务处理函数:每组包含
function_i_1和function_i_2两个函数,均返回字符串,且参数必须是Data_i类型的实例
最初我用以下方式实现调度逻辑:
def solve(problem_number, task_number): g = globals() g[f'function{problem_number}_{task_number}'](g[f'load_data_{problem_number}']())
这种写法虽然符合DRY原则,但既粗糙不优雅,也完全无法提供类型提示支持。
我尝试过几种改进思路,但都存在缺陷:
- 定义包含
function_1、function_2抽象方法和solve方法的Solver基类,再编写25个继承子类,但每个子类需要处理不同的数据类型,类型提示无法妥善处理 - 给
Solver类添加data属性,直接持有数据实例,但这违背了数据结构与逻辑分离的设计原则 - 使用协议(Protocols),但始终会碰到上述两个问题中的一个
我更熟悉C++,在C++中可以通过模板类实现通用逻辑,再针对25种数据类型显式实例化来解决这类问题。因此提出两个问题:
- Python中能否实现类似C++模板的方案?如果可以,具体怎么操作?
- 如果无法实现,有没有符合mypy类型检查规范的更优雅实现方式?
最小示例(仅含两种数据类型)
from pathlib import Path # 定义数据类型 Data1 = str Data2 = float # 数据加载函数 def load_data_1(file_path: Path) -> Data1: with open(file_path) as f: return f.read() def load_data_2(file_path: Path) -> Data2: with open(file_path) as f: return float(f.readline()) # 任务处理函数 def function_1_1(data: Data1) -> str: return data.strip() def function_1_2(data: Data1) -> str: return data.upper() def function_2_1(data: Data2) -> str: return f'{data < 0}' def function_2_2(data: Data2) -> str: return f'{data > 3.16}' # 原始主调度函数 def main(problem_number: int, task_number: int) -> None: g = globals() function_to_call = g[f'function{problem_number}_{task_number}'] data_loader = g[f'load_data_{problem_number}'] data_path = f'/path/to/data_{problem_number}.txt' print(function_to_call(data_loader(Path(data_path))))
内容的提问来源于stack exchange,提问作者5xum
相关产品推荐
相关产品推荐

