Python装饰器能否用于模拟函数试验?如何实现可自定义试验次数的方案
代码修复与优化方案
首先梳理你原有代码存在的问题:
- 被装饰函数
DiceRolls冗余声明了num_trials参数,该参数已经由装饰器的包装函数接收处理,不需要在业务执行函数里重复定义 - 装饰器的包装函数中
num_trials被定义为强制关键字参数,调用时必须显式指定参数名,同时你原调用语句里的num_trials是未赋值的变量,需要传入具体的数值 - 可以进一步优化装饰器结构,支持装饰时指定默认试验次数,使用灵活度更高
最小改动修复版本
仅调整错误点即可正常运行:
from functools import wraps from random import randint def DiceRoll(dice_size=6): return randint(1, dice_size) def trials(func): @wraps(func) def wrapper(*args, num_trials, **kwargs): results = [] for _ in range(num_trials): result = func(*args, **kwargs) results.append(result) return results return wrapper @trials def DiceRolls(dice_size=6): # 移除冗余的num_trials参数 return DiceRoll(dice_size) # 调用时显式指定num_trials关键字参数,传入具体试验次数 print(DiceRolls(num_trials=10)) # 也可同时指定骰子规格 print(DiceRolls(dice_size=12, num_trials=5))
更优雅的通用实现版本
改造为支持默认试验次数的带参装饰器,兼容默认配置和临时调整需求:
from functools import wraps from random import randint def DiceRoll(dice_size=6): return randint(1, dice_size) # 带参数的装饰器,支持设置默认试验次数 def trials(default_num: int = 3): def decorator(func): @wraps(func) def wrapper(*args, num_trials: int = None, **kwargs): run_times = num_trials if num_trials is not None else default_num return [func(*args, **kwargs) for _ in range(run_times)] return wrapper return decorator # 装饰时指定默认执行5次 @trials(default_num=5) def DiceRolls(dice_size=6): return DiceRoll(dice_size) # 用默认配置执行:掷6面骰5次 print(DiceRolls()) # 临时调整执行次数:掷6面骰10次 print(DiceRolls(num_trials=10)) # 同时调整参数和执行次数:掷12面骰8次 print(DiceRolls(dice_size=12, num_trials=8))
内容的提问来源于stack exchange,提问作者Brad Graham
相关产品推荐
相关产品推荐

