我正在定义如下的Python单例:
class Database:
initialized = False
def __init__(self):
self.id = random.randint(1,101)
print("Generated an id of ", self.id)
print("Loading database from file")
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Database, cls)\
.__new__(cls, *args, **kwargs)
return cls._instance
在某种意义上说,对Database()
的每次调用实际上都返回一个实例。但是,在每次调用时都会调用__init__()
方法 still 。例如,
database = Database()
if __name__ == '__main__':
d1 = Database()
d2 = Database()
print(d1.id, d2.id)
print(d1 == d2)
print(database == d1)
产生输出
Generated an id of 8
Loading database from file
Generated an id of 89
Loading database from file
Generated an id of 81
Loading database from file
81 81
True
True
那是为什么?如何避免初始化程序被多次调用?
答案 0 :(得分:1)
创建实例包括两个步骤:①通过调用cls.__new__()
创建一个“空白”实例,然后②通过调用obj.__init__()
初始化此空白实例。
在您的情况下,创建类的新实例将调用您的__new__()
,该实例总是返回相同(不是很空白)的实例,然后通过在其中调用__init__()
对其进行正确初始化(抱歉pun)。
我不确定是否有办法避免调用__init__()
,至少没有简单的方法。我会接受这一点,只是保留一个空的__init__()
,它在被调用时不会受到伤害。
或者,也许通常最好不要创建单例的新实例(由于特殊的__new__()
方法,因此恰好是 same 实例) 。相反,只需使用cls.singleton
来存储您唯一的一个实例(单例),或者仅使用类本身作为单例并在类和静态方法中进行所有操作。我通常会选择后者。