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>
    
  • 相关阅读:
    hdu 5387 Clock (模拟)
    CodeForces 300B Coach (并查集)
    hdu 3342 Legal or Not(拓扑排序)
    hdu 3853 LOOPS(概率DP)
    hdu 3076 ssworld VS DDD(概率dp)
    csu 1120 病毒(LICS 最长公共上升子序列)
    csu 1110 RMQ with Shifts (线段树单点更新)
    poj 1458 Common Subsequence(最大公共子序列)
    poj 2456 Aggressive cows (二分)
    HDU 1869 六度分离(floyd)
  • 原文地址:https://www.cnblogs.com/linagcheng/p/9548308.html
Copyright © 2011-2022 走看看