Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python类中的两个构造函数_Python_Python 2.7 - Fatal编程技术网

Python类中的两个构造函数

Python类中的两个构造函数,python,python-2.7,Python,Python 2.7,有两个构造函数可以吗,一个是常规的\uuuu init\uuu函数,一个是@classmethod

有两个构造函数可以吗,一个是常规的
\uuuu init\uuu
函数,一个是
@classmethod

由于创建新对象需要大量计算,因此我们希望将以前创建的实例存储在class属性
cls.zoo
中,并从
cls.zoo
获取实例的缓存副本(如果存在)

用户将无法直接访问
Animal.zoo
。如果用户想要获取一个
Animal
对象,他将始终使用
Animal.get()

这种方法合适吗

我不熟悉单身模式。代码是否考虑使用单例模式

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')

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

如果确实只需要一个实例,则可以使用
\uuuu new\uuu

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

如果这是一个你认为可以改进的工作代码,考虑一下(虽然他们想要实际代码,而不是一个虚拟例子)。这是真的代码吗?它可能是演示/播放代码,这对于代码审查来说是离题的。相反,通过类方法的替代构造函数没有错。这是演示/播放代码,所以我发布到so。如果缓存对象可用,用户将被迫使用它。在这种情况下,您将如何决定何时使用
\uuuu new\uuuu
classmethod
?@Nyxynyx:使用class方法,用户始终可以创建一个新对象而不使用它。为每个新实例调用
\uuuuuuuuuuuuuuuuuuuuuuuu
方法。因此,如果您希望始终使用缓存,
\uuuuuu new\uuuuu
更安全。