【python】Python的单例模式

原文:http://blog.csdn.net/ghostfromheaven/article/details/7671853

单例模式:保证一个类仅有一个实例,并提供一个访问他的全局访问点。

实现某个类只有一个实例的途径:

1,让一个全局变量使得一个对象被访问,但是他不能防止外部实例化多个对象。

2,让类自身保存他的唯一实例,这个类可以保证没有其他实例可以被创建。

多线程时的单例模式:加锁-双重锁定

饿汉式单例类:在类被加载时就将自己实例化(静态初始化)。其优点是躲避了多线程访问的安全性问题,缺点是提前占用系统资源。

懒汉式单例类:在第一次被引用时,才将自己实例化。避免开始时占用系统资源,但是有多线程访问安全性问题。

 下面是实现单例模式的4中方法:

  1 #-*- encoding=utf-8 -*-
  2 print '----------------------方法1--------------------------'
  3 #方法1,实现__new__方法
  4 #并在将一个类的实例绑定到类变量_instance上,
  5 #如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回
  6 #如果cls._instance不为None,直接返回cls._instance
  7 class Singleton(object):
  8     def __new__(cls, *args, **kw):
  9         if not hasattr(cls, '_instance'):
 10             orig = super(Singleton, cls)
 11             cls._instance = orig.__new__(cls, *args, **kw)
 12         return cls._instance
 13 
 14 class MyClass(Singleton):
 15     a = 1
 16 
 17 one = MyClass()
 18 two = MyClass()
 19 
 20 two.a = 3
 21 print one.a
 22 #3
 23 #one和two完全相同,可以用id(), ==, is检测
 24 print id(one)
 25 #29097904
 26 print id(two)
 27 #29097904
 28 print one == two
 29 #True
 30 print one is two
 31 #True
 32 
 33 print '----------------------方法2--------------------------'
 34 #方法2,共享属性;所谓单例就是所有引用(实例、对象)拥有相同的状态(属性)和行为(方法)
 35 #同一个类的所有实例天然拥有相同的行为(方法),
 36 #只需要保证同一个类的所有实例具有相同的状态(属性)即可
 37 #所有实例共享属性的最简单最直接的方法就是__dict__属性指向(引用)同一个字典(dict)
 38 #可参看:http://code.activestate.com/recipes/66531/
 39 class Borg(object):
 40     _state = {}
 41     def __new__(cls, *args, **kw):
 42         ob = super(Borg, cls).__new__(cls, *args, **kw)
 43         ob.__dict__ = cls._state
 44         return ob
 45 
 46 class MyClass2(Borg):
 47     a = 1
 48 
 49 one = MyClass2()
 50 two = MyClass2()
 51 
 52 #one和two是两个不同的对象,id, ==, is对比结果可看出
 53 two.a = 3
 54 print one.a
 55 #3
 56 print id(one)
 57 #28873680
 58 print id(two)
 59 #28873712
 60 print one == two
 61 #False
 62 print one is two
 63 #False
 64 #但是one和two具有相同的(同一个__dict__属性),见:
 65 print id(one.__dict__)
 66 #30104000
 67 print id(two.__dict__)
 68 #30104000
 69 
 70 print '----------------------方法3--------------------------'
 71 #方法3:本质上是方法1的升级(或者说高级)版
 72 #使用__metaclass__(元类)的高级python用法
 73 class Singleton2(type):
 74     def __init__(cls, name, bases, dict):
 75         super(Singleton2, cls).__init__(name, bases, dict)
 76         cls._instance = None
 77     def __call__(cls, *args, **kw):
 78         if cls._instance is None:
 79             cls._instance = super(Singleton2, cls).__call__(*args, **kw)
 80         return cls._instance
 81 
 82 class MyClass3(object):
 83     __metaclass__ = Singleton2
 84 
 85 one = MyClass3()
 86 two = MyClass3()
 87 
 88 two.a = 3
 89 print one.a
 90 #3
 91 print id(one)
 92 #31495472
 93 print id(two)
 94 #31495472
 95 print one == two
 96 #True
 97 print one is two
 98 #True
 99 
100 print '----------------------方法4--------------------------'
101 #方法4:也是方法1的升级(高级)版本,
102 #使用装饰器(decorator),
103 #这是一种更pythonic,更elegant的方法,
104 #单例类本身根本不知道自己是单例的,因为他本身(自己的代码)并不是单例的
105 def singleton(cls, *args, **kw):
106     instances = {}
107     def _singleton():
108         if cls not in instances:
109             instances[cls] = cls(*args, **kw)
110         return instances[cls]
111     return _singleton
112 
113 @singleton
114 class MyClass4(object):
115     a = 1
116     def __init__(self, x=0):
117         self.x = x
118 
119 one = MyClass4()
120 two = MyClass4()
121 
122 two.a = 3
123 print one.a
124 #3
125 print id(one)
126 #29660784
127 print id(two)
128 #29660784
129 print one == two
130 #True
131 print one is two
132 #True
133 one.x = 1
134 print one.x
135 #1
136 print two.x
137 #1

 

posted @ 2013-09-04 08:37  DeanWu的博客  阅读(429)  评论(0编辑  收藏  举报