单例模式

Posted smart1san

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式相关的知识,希望对你有一定的参考价值。

一、什么是单例模式

  基于某种方法的前提下,实例化多次的得到的实例是同一个。

二、为何用单例模式

  在没有使用单例模式的前提下,在实例化的时候,每当我们实例化一次,就会产生一个新的内存地址,占用一份内存的空间资源。

  所以,当实例化多次得到的对象中存放的属性都一样的情况下,应该将多个对象指向同一个内存,即同一个实例,这样可以减少内存资源的过度浪费。

三、单例的实现方式

技术分享图片
IP=1.1.1.1
PORT=3306
settings
技术分享图片
import settings
class mysql:
    __instance=None
    def __init__(self,ip,port):
        self.ip=ip
        self.port=port
    @classmethod
    def get_info_from_conf(cls):
        if cls.__instance is None:
            cls.__instance=cls(settings.IP,settings.PORT)
        return cls.__instance
# 正常实例化一次即占用一份内存资源
# obj1=Mysql(‘192.168.0.0‘,3306)
# obj2=Mysql(‘192.168.0.0‘,3306)
# obj3=Mysql(‘192.168.0.0‘,3306)
#
# print(id(obj1))     #2362806290360
# print(id(obj2))     # 2362806290416
# print(id(obj3))     #2362806290528

# 使用单例模式之后占用同一份内存资源
obj1=Mysql.get_info_from_conf()
obj2=Mysql.get_info_from_conf()
obj3=Mysql.get_info_from_conf()

print(obj1.__dict__)
print(id(obj1))    # 1591701587896
print(id(obj2))    # 1591701587896
print(id(obj3))    # 1591701587896
方式一
技术分享图片
# 通过自定义装饰器来实现

import settings
def singleton(cls):
    cls.__instance=cls(settings.IP,settings.PORT)
    def wrapper(*args,**kwargs):
        if len(args)==0 and len(kwargs)==0:
            return cls.__instance
        return cls(*args,**kwargs)
    return wrapper


@singleton
class Mysql:
    def __init__(self,ip,port):
        self.ip=ip
        self.port=port

obj1=Mysql()
obj2=Mysql()

print(obj1.__dict__)
print(id(obj1))   # 1452804392832
print(id(obj2))   # 1452804392832
方式二
技术分享图片
 1 # 自定义元类来实现实例化
 2 import settings
 3 class Mymeta(type):
 4     def __init__(self,class_name,class_bases,class_dic):
 5         super(Mymeta, self).__init__(class_name,class_bases,class_dic)
 6         # 造出一个Mysql的空对象
 7         self.__instance=self.__new__(self)
 8         # 为空对象从文件中读取数据并完成初始化
 9         self.__init__(self.__instance,settings.IP,settings.PORT)
10     
11     # 在调用时会自动触发__call__方法
12     def __call__(self, *args, **kwargs):
13         if len(args)==0 and len(kwargs)==0:
14             return self.__instance
15         obj=self.__new__(self)
16         self.__init__(obj,*args,**kwargs)
17         return obj
18 
19 class Mysql(object,metaclass=Mymeta):
20     def __init__(self,ip,port):
21         self.ip=ip
22         self.port=port
23         
24 obj1=Mysql()
25 obj2=Mysql()
26 
27 print(id(obj1))  # 2028744394680
28 print(id(obj2))  # 2028744394680
方式三

 

以上是关于单例模式的主要内容,如果未能解决你的问题,请参考以下文章

常用代码片段

性能比较好的单例写法

片段作为 Android 中的单例

单例片段或保存网页视图状态

你熟悉的设计模式都有哪些?写出单例模式的实现代码

单例模式以及静态代码块