zoukankan      html  css  js  c++  java
  • Python 中的单例模式

    单例模式

    单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

    比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。

    在 Python 中,我们可以用多种方法来实现单例模式:

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 
     4 # 方式1
     5 class Singleton():
     6     def __new__(cls, *args, **kwargs):
     7         if not hasattr(cls,'_instance'):
     8             orig = super(Singleton, cls)
     9             cls._instance = orig.__new__(cls,*args,**kwargs)
    10         return cls._instance
    11 
    12 
    13 class MyClass(Singleton):
    14     a=1
    15 
    16 one = MyClass()
    17 two = MyClass()
    18 two.a = 3
    19 print(one.a)
    20 print(id(one))
    21 print(id(two))
    22 print('-------------------------------')
    23 
    24 #方式2
    25 class Borg(object):
    26     _state = {}
    27     def __new__(cls, *args, **kwargs):
    28         ob = super(Borg, cls).__new__(cls, *args, **kwargs)
    29         ob.__dict__ = cls._state
    30         return ob
    31     def __hash__(self):
    32         return 1
    33     def __eq__(self, other):
    34         try:
    35             return self.__dict__ is other.__dict__
    36         except:
    37             return False
    38 
    39 class MyClass2(Borg):
    40     a = 1
    41 
    42 a = MyClass2()
    43 b = MyClass2()
    44 c = MyClass2()
    45 # a.a = 11
    46 # b.a = 12
    47 # c.a = 13
    48 # print(a.a, b.a, c.a)
    49 
    50 adict = {}
    51 j = 0
    52 for i in a, b, c:
    53     adict[i] = j
    54     j += 1
    55 for i in a, b, c:
    56     print(adict[i])
    57 
    58 print('-------------------------------')
    59 
    60 # 方式3 当你编写一个类的时候,某种机制会使用类名字,基类元组,类字典来创建一个类对象。新型类中这种机制默认为type,而且这种机制是可编程的,称为元类__metaclass__
    61 class Singleton2(type):
    62     def __init__(self,name,bases,class_dict):
    63         super(Singleton2,self).__init__(name,bases,class_dict)
    64         self._instance=None
    65     def __call__(self, *args, **kwargs):
    66         if self._instance is None:
    67             self._instance= super(Singleton2, self).__call__(*args, **kwargs)
    68         return self._instance
    69 
    70 class A(object):
    71     __metaclass__ = Singleton2
    72 a = A()
    73 b = A()
    74 print(id(a), id(b))
    75 
    76 print('-------------------------------')
    77 
    78 # 方法4 python并不会对sys.modules进行检查以确保他们是模块对象,我们利用这一点将模块绑定向一个类对象,而且以后都会绑定向同一个对象了
    79 class _singleton(object):
    80     class ConstError(TypeError):
    81         pass
    82     def __setattr__(self, key, value):
    83         if key in self.__dict__:
    84             raise self.ConstError
    85         self.__dict__[key]=value
    86     def __delattr__(self, item):
    87         if item in self.__dict__:
    88             raise self.ConstError
    89         raise NameError
    90 import sys
    91 sys.modules[__name__] = _singleton()
  • 相关阅读:
    【机器学习】关于判别模型和生成模型
    Delphi新手跟我学写CALL,附完整原程序
    QT事件研究的文章
    杂烩:QWidget、QGraphics、QtQuick
    Golang全接触
    学会使用git
    代码创建 WPF 旋转动画
    值得推荐的C/C++框架和库 very good
    可恶的QT隐式共享
    Notes on OpenSSL and Qt(ssl.pri,qsslocket_openssl_symbols.cpp)
  • 原文地址:https://www.cnblogs.com/crucial/p/6445908.html
Copyright © 2011-2022 走看看