• Python单例模式的4种实现方法


    转自:http://ghostfromheaven.iteye.com/blog/1562618
     
    Python代码  收藏代码
    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):  
    106.     instances = {}  
    107.     def _singleton(, *args, **kw):  
    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  
  • 相关阅读:
    iphone 使用委托(delegate)在不同的窗口之间传递数据
    创建单键模式的类
    读入Plist文件中的信息
    C#读取Excel,取值为空的解决办法!
    ORACLE 常见的数据类型
    ArcGISServer 将内网地图服务映射修改外网可以访问的地图服务
    C#中获取当前路径的几种方法
    sql server2005登录出错问题(转载)
    (转载)服务器控件的生命周期
    ORACLE 中ROWNUM用法总结(转载)
  • 原文地址:https://www.cnblogs.com/ymy124/p/5048805.html
Copyright © 2020-2023  润新知