为什么一个base class单例还会多次调用构造函数?
Why does a base class singleton still call the constructor mulitple times?
我正在定义一个 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()
的每一次调用实际上都是 returns 一个且唯一的实例。但是,__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
这是为什么?我该怎么做才能避免多次调用初始化程序?
创建一个实例分为两个步骤:①通过调用cls.__new__()
创建一个"blank"实例,然后②通过调用obj.__init__()
.
初始化这个空白实例
在你的例子中,创建你的 class 的新实例调用你的 __new__()
,它总是 returns 相同的(不是那么空白的)实例,然后通过调用 [= =13=] 在其中(抱歉双关语)。
我不确定是否有办法避免调用 __init__()
,我认为至少没有直接的方法。我会接受这一点,只保留一个空的 __init__()
,调用时不会受到伤害。
或者,也许最好不要创建新的单例实例(由于您的特殊 __new__()
方法)。相反,只需使用 cls.singleton
来存储您的唯一实例(单例)或仅使用 class 本身作为单例并在 class 和静态方法中制作所有内容。我通常选择后一种选择。
我正在定义一个 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()
的每一次调用实际上都是 returns 一个且唯一的实例。但是,__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
这是为什么?我该怎么做才能避免多次调用初始化程序?
创建一个实例分为两个步骤:①通过调用cls.__new__()
创建一个"blank"实例,然后②通过调用obj.__init__()
.
在你的例子中,创建你的 class 的新实例调用你的 __new__()
,它总是 returns 相同的(不是那么空白的)实例,然后通过调用 [= =13=] 在其中(抱歉双关语)。
我不确定是否有办法避免调用 __init__()
,我认为至少没有直接的方法。我会接受这一点,只保留一个空的 __init__()
,调用时不会受到伤害。
或者,也许最好不要创建新的单例实例(由于您的特殊 __new__()
方法)。相反,只需使用 cls.singleton
来存储您的唯一实例(单例)或仅使用 class 本身作为单例并在 class 和静态方法中制作所有内容。我通常选择后一种选择。