python的单例,有疑惑

模仿《python 3 patterns》写单例,我是python2.7

1、内部类实现方式

class OnlyOne:
    class __OnlyOne:
        def __init__(self,arg):
            self.val=arg
        def __str__(self):
            return self.val
    instance =None
    def __init__(self,arg):
        if not OnlyOne.instance:
            OnlyOne.instance=OnlyOne.__OnlyOne(arg) 
        else:
            OnlyOne.instance.val=arg
    def __getattr__(self,name):
        return getattr(self.instance,name)
    
x=OnlyOne('sausage')
print x
y=OnlyOne('eggs')
print y
z=OnlyOne('spam')
print z
print y
print x
print id(x),id(y),id(z)
print x is z
print y==z

 

能预计到x,y,z的值都是spam,但是x,y,z的内存却不是同一个,这个让我很疑惑,输出如下:

pydev debugger: starting
sausage
eggs
spam
spam
spam
43746128 43746048 43746248
False
False

而在该书上输出的地址是一致的,

2、使用同一个字典方式(书中命名为Borg)

class Borg:
    _shared_state={}
    def __init__(self):
        self.__dict__=self._shared_state
        
class Singleton(Borg):
    def __init__(self,arg):
        Borg.__init__(self)
        self.val=arg
    def __str__(self):return self.val
    
x=Singleton('sausage')
y=Singleton('eggs')
z=Singleton('spam')

print x,y,z
print id(x),id(y),id(z)

输出

pydev debugger: starting
spam spam spam
45126760 45126640 45126720

3、使用类变量

class SingleTone(object):
    __instance=None
    def __new__(cls,val):
        if SingleTone.__instance is None:
            SingleTone.__instance=object.__new__(cls)
        SingleTone.__instance.val=val
        return SingleTone.__instance

4、装饰器模式

  a\

      

class SingletonDecorator:
    def __init__(self,klass):
        self.klass=klass
        self.instance=None
    
    def __call__(self,*args,**kwds):
        if self.instance==None:
            self.instance=self.klass(*args,**kwds)
        return self.instance

class foo:pass
foo=SingletonDecorator(foo)
#也是可以
#@SingletonDecorator
#class foo: pass
x=foo()
y=foo()
z=foo()

x.val='sausage'
y.val='eggs'
z.val='spam'
print (z.val)
print (x.val)
print (y.val)
print (x is y is z)  #True

5、元类方式

posted @ 2013-10-21 14:59  tree.liang  阅读(361)  评论(0编辑  收藏  举报