Python类中的两个构造函数

时间:2015-11-22 19:29:20

标签: python python-2.7

是否可以使用2个构造函数,常规__init__@classmethod Animal.get

由于创建新对象是计算密集型的,因此我们希望将先前创建的实例存储在类属性cls.zoo中,并从cls.zoo获取实例的缓存副本(如果存在)。

用户不会直接访问Animal.zoo。如果用户想要获得Animal个对象,他将始终使用Animal.get()

这种方法是正确的/ pythonic吗?

我不熟悉Singleton模式。是否使用Singleton模式考虑了代码?

class Animal:

    zoo = {}

    # will not be called directly from outside the class
    def __init__(self, species ,age):
        self.species = species
        self.age = age
        self.runExpensiveFunction()

    # User alway use this function
    @classmethod
    def get(cls, species):
        if species in cls.zoo:
            animal = cls.zoo[species]
        else:
            animal = Animal(species, 0)
            cls.zoo[species] = animal

        return animal

tiger = Animal.get('tiger')
bear = Animal.get('bear')

1 个答案:

答案 0 :(得分:3)

这取决于您是否只想允许类的用户访问缓存对象,或者是否要强制它只访问该缓存对象。有了您的解决方案,用户始终可以使用tiger2 = Animal('tiger', 0)来获取另一个实例。

如果您真的只想要一个实例,可以使用__new__

class Animals(object):
    zoo = {}
    def runExpensiveFunction(self):
        print "EXPENSIVE CALLED"
    def __new__(cls, species):
        if species in cls.zoo:
            return cls.zoo[species]
        else:
            animal = object.__new__(Animals)
            animal.species = species
            animal.age = 0
            animal.runExpensiveFunction()
            Animals.zoo[species] = animal
            return animal

以下是您只能创建一个实例的证据:

>>> tiger1 = Animals('tiger')
EXPENSIVE CALLED
>>> tiger2 = Animals('tiger')
>>> tiger2 is tiger1
True