我有一个RoundRobinChecker
和一个PlayoffChecker
类,都继承自ViolationChecker
,它会检查给定的循环赛或季后赛是否符合规则。
构造函数有一个参数,匹配:ViolationChecker(match)
。现在,如果匹配是季后赛匹配(match.playoff
),则应该PlayoffChecker
实例化,否则它应该是RoundRobinChecker
。我可以这样做:
checkers = [PlayoffChecker(match) if match.playoff else RoundRobinChecker(match) for match in matches]
但这是一种不干净的做法。是否可以只调用父类构造函数ViolationChecker(match)
,这会创建相应子类的实例吗?
我可以在这里用什么设计以透明的方式选择合适的课程?
答案 0 :(得分:2)
为了使ViolationChecker(match)
有效,您可以覆盖父类中的__new__
method,如下所示:
class ViolationChecker:
def __new__(cls, match):
if match.playoff:
cls= PlayoffChecker
else:
cls= RoundRobinChecker
inst= object.__new__(cls)
return inst #implicit call to inst.__init__(match)
但是,对于读取代码的人来说ViolationChecker(match)
返回子类的实例并不明显。我建议为ViolationChecker
添加一个名称清晰的静态方法,如下所示:
class ViolationChecker:
@staticmethod
def new_for_match(match):
if match.playoff:
cls= PlayoffChecker
else:
cls= RoundRobinChecker
inst= cls(match)
return inst
现在您可以执行ViolationChecker.new_for_match(match)
,这样可以更清楚地表达为此ViolationChecker
实例专门创建match
的意图。