基于参数来学习不同的子类

时间:2017-06-20 08:56:29

标签: python python-2.7 oop

我有一个RoundRobinChecker和一个PlayoffChecker类,都继承自ViolationChecker,它会检查给定的循环赛或季后赛是否符合规则。

构造函数有一个参数,匹配:ViolationChecker(match)。现在,如果匹配是季后赛匹配(match.playoff),则应该PlayoffChecker实例化,否则它应该是RoundRobinChecker。我可以这样做:

checkers = [PlayoffChecker(match) if match.playoff else RoundRobinChecker(match) for match in matches]

但这是一种不干净的做法。是否可以只调用父类构造函数ViolationChecker(match),这会创建相应子类的实例吗?

我可以在这里用什么设计以透明的方式选择合适的课程?

1 个答案:

答案 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的意图。