是否可以使用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')
答案 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