码迷,mamicode.com
首页 > 其他好文 > 详细

单例模式

时间:2019-10-06 20:59:49      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:内容   python   入参   inf   内存   sql   png   执行   设计   

单例模式

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

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

什么是单例:

  单例是指单个实例,指一个类只能有一个实例对象

为什么要使用单例?

  当一个类的实例中的数据不会变化时使用单例,数据是不变的;在优酷系统中orm的书写有用到;

单例模式:

  多次实例化结果指向同一个实例

开设单例模式的方法有许多种,常用的有以下5种方式:

第一种:基于classmethod

  .绑定到类的方法:用classmethod装饰器装饰的方法。

  特点:参数的第一个必须是cls表示当前类本身,使用类名来调用,调用时会自动传入类

相关知识点:

"""
1.类由type创建,创建类时,type的__init__方法自动执行,类() 执行type的 __call__方法(类的__new__方法,类的__init__方法)
2.对象由类创建,创建对象时,类的__init__方法自动执行,对象()执行类的 __call__ 方法
"""

开设单例:

class Mysql(object):
    _instance = None 单例

    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

    @classmethod
    def singleton(cls):
        if not cls._instance:
            cls._instance = Mysql(127.0.0.1, 3306)
        return cls._instance


obj1 = Mysql.singleton()
obj2 = Mysql.singleton()
print(obj1)
print(obj2)

 

运行的结果:

技术图片

 

 第二种(基于装饰器),自定义的

def singleton(cls):
    # 该对象在类Mysql被装饰上singleton的时候就已经实例化完毕
    _instance = cls(127.0.0.1,3306)
    def inner(*args,**kwargs):
        # 判断是否传入参数,传入参数表示要实例化新的,不传表示用默认的
        if args or kwargs:
            obj = cls(*args,**kwargs)
            return obj
        return _instance
    return inner

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

obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
print(obj1,obj2,obj3)

 

运行的结果是得到指向的是同一个内存地址

技术图片

 

 第三种是基于元类的单例模式(type)

class MymetaClass(type):
    def __call__(self, *args, **kwargs):
        if not hasattr(self,instance):
            self.instance = super().__call__(*args,**kwargs)
        return self.instance

class Mysql(metaclass=MymetaClass):
    def __init__(self,host,port):
        self.host = host
        self.port = port
obj = Mysql(ajdak,213)
obj1 = Mysql(asdasdas,134234)
print(obj,obj1)

结果:

技术图片

 

 第四种(基于__new__)

  元类中__new__是用于创建类对象的 ,__init__是用于初始化类的其他信息的.

我们知道,当我们实例化一个对象时,是先执行了类的__new__方法(我们没写时,默认调用object.__new__),实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,所有我们可以基于这个,实现单例模式

class Mysql(object):
    _instance = None
    def __init__(self,name):
        self.name = name

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = object.__new__(cls)
        return cls._instance

obj = Mysql(egon)
obj1 = Mysql(jason)
print(id(obj),id(obj1))

 

技术图片

第五种(基于模块)

  其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了

# 单独在一个py文件中定义一个类,并实例化一个对象,之后在其他文件导入这一对象,实现单例
class Singleton(object):
    def __init__(self,host,port):
        self.host = host
        self.port = port

singleton = Singleton(127.0.0.1,3306)

 

 

 

 

 

  

 

  

单例模式

标签:内容   python   入参   inf   内存   sql   png   执行   设计   

原文地址:https://www.cnblogs.com/Gaimo/p/11628183.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!