【问题标题】:Should a class constructor return a subclass?类构造函数应该返回子类吗?
【发布时间】:2012-09-15 00:35:07
【问题描述】:

类构造函数应该返回子类吗?

这主要是关于OOP风格和python风格的问题。我遇到了需要实现通用案例解决方案的问题,出于性能原因,我需要为特定输入类型实现优化的解决方案。输入类型取决于用户。目前,我已经通过对一般案例解决方案进行子类化以制作优化解决方案来实现这一点。我想出了下面的例子来帮助描述我的意思。

from collections import Counter

class MyCounter(object):
    """General Case Counter"""
    def __init__(self, seq):
        self.seq = seq

    def count(self, key):
        return sum(key == item for item in self.seq)


class OptimizedCounter(MyCounter):
    """Counter optimized for hashable types"""
    def __init__(self, seq):
        self.counter = Counter(seq)

    def count(self, key):
        return self.counter.get(key, 0)

counter = MyCounter(['a', 'a', 'b', [], [0, 1]])
counter.count([0, 1])
# 1

counter = OptimizedCounter(['a', 'a', 'b'])
counter.count('a')
# 2

我的问题是如何设计一个流畅的界面,以便用户获得合适的实例,而不必担心它是如何实现的。我考虑过做类似以下的事情,但这对我来说感觉很难看。有没有更规范或 OOP 的方式来做这样的事情?

class MyCounter(object):
    """General Case Counter"""
    def __new__(cls, seq):
        if hasOnlyHashables(seq):
            return object.__new__(OptimizedCounter)
        else:
            return object.__new__(MyCounter)

【问题讨论】:

    标签: python oop coding-style


    【解决方案1】:

    使用返回适当类的实例的工厂函数。

    def makeCounter(seq):
        if hasOnlyHashables(seq):
            return OptimizedCounter(seq)
        else:
            return MyCounter(seq)
    

    【讨论】:

      【解决方案2】:

      您的分配器实现有点偏离。如果您需要创建子(或不同)类型的实例,那么您可以通过调用 its 构造函数来实现;只有当你想创建 current 类的实例时,你才应该调用父级(在这种情况下为object)分配器。

      【讨论】:

        【解决方案3】:

        不,类构造函数不返回任何内容。

        您需要按照 BrenBarn 的建议创建一个工厂,但我会将该工厂作为静态方法放在最通用的类​​中。

        类似这样的:

        class MyCounter(object):
            @staticmethod
            def from_seq(cls, seq):
                if hasOnlyHashables(seq):
                    return OptimizedCounter(seq)
                else:
                    return MyCounter(seq)
        
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-09
          相关资源
          最近更新 更多