zoukankan      html  css  js  c++  java
  • 面向对象(七)——单例模式4种实现方式

    单例模式

    一、什么是单例

    即单个实例,指的是同一个类实例化多次的结果指向同一个对象,用于节省内存空间

    如果我们从配置文件中读取配置来进行实例化,在配置相同的情况下,就没必要重复产生对象浪费内存了

    # settings.py文件
    IP = '1.1.1.1'
    PORT = 3303

    二、四种单例模式的实现方式

    # 方式一:定义一个类方法实现单例模式
    
    import settings
    
    class People:
        __instance = None    #用于保存实例化的状态
    
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
        @classmethod
        def get(cls):
            if cls.__instance is None:
                cls.__instance = cls(settings.IP, settings.PORT)
            return cls.__instance
    
    
    obj1 = People.get()
    obj2 = People.get()
    print(obj1)
    print(obj2)
    # <__main__.People object at 0x00000000021BA9B0>
    # <__main__.People object at 0x00000000021BA9B0>
    
    
    
    
    #方式二:定义一个装饰器实现单例模式
    import settings
    
    def singlet(cls):
        _instance = cls(settings.IP, settings.PORT)   #先实例化一个对象
    
        def wrapper(*args, **kwargs):
            if args or kwargs:
                obj = cls(*args, **kwargs)
                return obj        #有参数是返回后来实例化对象
            return _instance         #无参时,返回已经实例化好的对象
    
        return wrapper
    
    
    @singlet    # MySQL=wrapper(MySQL)
    class MySQL:
    
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
    
    # 没有参数时,单例模式
    obj1 = MySQL()
    obj2 = MySQL()
    obj3 = MySQL()
    obj4 = MySQL('1.1.1.1', 3303)
    print(obj1)
    print(obj2)
    print(obj3)
    print(obj4)
    # <__main__.MySQL object at 0x0000000001E6AA90>
    # <__main__.MySQL object at 0x0000000001E6AA90>
    # <__main__.MySQL object at 0x0000000001E6AA90>
    # <__main__.MySQL object at 0x0000000001E6AB00>
    
    
    #方式三:定制元类实现单例模式
    import settings
    
    class Mymeta(type):
        def __init__(self, class_name, class_bases, class_dic):
            instance = self(settings.IP, settings.PORT)
            self.__instance = instance
    
        def __call__(self, *args, **kwargs):         # self=MySQL
            if args or kwargs:          #  有参数执行下面的代码
                obj = self.__new__(self)          #创造一个空对象
                self.__init__(obj, *args, **kwargs)          #初始化
                return obj             #返回对象
            return self.__instance
    
    
    class MySQL(metaclass=Mymeta):
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
    
    obj1 = MySQL()
    obj2 = MySQL()
    obj3 = MySQL()
    obj4 = MySQL('1.2.3.1', 3305)
    print(obj1)
    print(obj2)
    print(obj3)
    print(obj4)
    # <__main__.MySQL object at 0x00000000021BAA90>
    # <__main__.MySQL object at 0x00000000021BAA90>
    # <__main__.MySQL object at 0x00000000021BAA90>
    # <__main__.MySQL object at 0x00000000021BAB00>
    
    
    方式四:利用模块导入实现单例模式
    # singleton模块
    import settings
    
    
    class MySQL:
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
    
    instance = MySQL(settings.IP, settings.PORT)
    
    #单例模块
    def f1():
        from singleton import instance
        print(instance)
    
    
    def f2():
        from singleton import instance, MySQL
        print(instance)
        obj = MySQL('1111', 3302)
        print(obj)
    
    
    f1()
    f2()
    
    # <singleton.MySQL object at 0x00000000021FAA90>
    # <singleton.MySQL object at 0x00000000021FAA90>
    # <singleton.MySQL object at 0x00000000021FA358>
    
  • 相关阅读:
    java 基础 01 变量和注释、数据类型
    js虚拟数字小键盘
    好看的table样式
    Java8的lambda表达式和Stream API
    设计模式-模板
    【转】Git使用教程之基础篇
    Linux安装redis和部署
    【原】DjianGo Windows7下的安装
    【转】七牛云加速域名配置
    【原】Solr入门之概念和安装
  • 原文地址:https://www.cnblogs.com/linagcheng/p/9548308.html
Copyright © 2011-2022 走看看