我正在学习如何在Python中创建单例(请不要讨论为什么单例不好,这不是这里的主题)。你知道吗
基于一个实现,我尝试这样做:
class Singleton(object):
def __init__(self, klass):
print "S init"
self.klass = klass
self.instance = None
def __call__(self, *args, **kwargs):
print "S call"
if self.instance is None:
self.instance = self.klass(*args, **kwargs)
else:
self.instance(*args, **kwargs)
return self.instance
@Singleton
class KlasseA:
def __new__(cls, *args, **kwargs):
print "KA new"
def __init__(self, s):
print "KA init"
self.__init2(s)
def __call__(self, s=None):
print "KA call"
self.__init2(s)
def __init2(self, s):
if s: self.s = s
@Singleton
class KlasseB:
def __new__(cls, *args, **kwargs):
print "KB new"
def __init__(self, s):
print "KB init"
self.__init2(s)
def __call__(self, s=None):
print "KB call"
self.__init2(s)
def __init2(self, s):
if s: self.s = s
现在,通过在同一.py文件中附加以下行来测试上述内容:
print ""
a = KlasseA('one')
print "a -> ", id(a), a.s
b = KlasseA('two')
print "b -> ", id(b), b.s
print "a -> ", id(a), a.s
c = KlasseA()
print "c -> ", id(c), c.s
print "b -> ", id(b), b.s
print "a -> ", id(a), a.s
d = KlasseB('three')
print "d -> ", id(d), d.s
print "a -> ", id(a), a.s
我得到以下信息:
S init
S init
S call
KA init
a -> 140525844905496 one
S call
KA call
b -> 140525844905496 two
a -> 140525844905496 two
S call
KA call
c -> 140525844905496 two
b -> 140525844905496 two
a -> 140525844905496 two
S call
KB init
d -> 140525844905568 three
a -> 140525844905496 two
所以,单体装饰器确实有效。我不明白的是:
我认为装饰器重新定义了调用,所以调用KlasseA()
实际上是对Singleton(KlasseA)()
的调用。这不应该为每个KlasseA()
调用生成一个新的Singleton
实例吗?
我注意到有两行“S init”,很可能是因为在声明KlasseA
和KlasseB
时调用了Singleton()
。因此,创建了Singleton
的两个实例。这些实例保存在哪里?
有没有一个可能的'抓到'与上述单一装饰配方?
Decorators是在定义类时应用的,而不是在实例化类时应用的。关于你的第一点,它实际上相当于:
关于第2点,名称
KlasseA
和KlasseB
绑定到Singleton
的实例,如上所示。你知道吗关于第3点,我不确定仅仅因为试图创建一个新实例就调用类的单个实例的
__call__
方法是否有意义。也就是说,我认为Singleton.__call__
应该是相关问题 更多 >
编程相关推荐