3

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

这主要是关于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)
4

3 回答 3

10

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

def makeCounter(seq):
    if hasOnlyHashables(seq):
        return OptimizedCounter(seq)
    else:
        return MyCounter(seq)
于 2012-09-15T00:36:12.450 回答
0

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

于 2012-09-15T00:46:31.147 回答
0

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

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

像这样的东西:

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

于 2022-02-10T18:07:40.510 回答