单例模式使用场景:

1、在程序中,多个模块中,使用该类的对象时:每个实例化对象都会有内存开销
2、日志收集器设置成单例模式:每个实例化日志对象后,每个日志对象会重复收集
3、数据库链接:1个脚本可能存在连接多次数据库,数据库最多允许多少个连接,在安装时有配置;
如果配置了100,当超出100后其他的对象连接不上,
使用单例模式,服务端数据库连接只有一个连接,在性能方面有个提升

案例一:实现单例模式

class Person(object):

    __obj=None

    def __new__(cls, *args, **kwargs):
        if cls.__obj is not None:
            cls.__obj=super().__new__(cls)
            #cls.obj=object.__new__(cls)
        return cls.__obj

if __name__ == '__main__':
    p=Person()
    p1=Person()
    p2=Person()

    print(id(p))
    print(id(p1))
    print(id(p2))

执行结果:
140711521459416
140711521459416
140711521459416

案例二:通过装饰器实现单例模式,只要任意一个类使用该装饰器装饰,那么就会变成一个单例模式的类

1、用函数装饰器实现

def Person(func):
    isinstance={}

    def wrapper(*args,**kwargs):
        if func in isinstance:
            return isinstance[func]
        else:
            isinstance[func]=func(*args,**kwargs)
            return isinstance[func]

    return wrapper

@Person                 #Demo=Person(Demo)
class Demo:
    print('开始执行')

if __name__ == '__main__':
    d1=Demo()
    d2=Demo()
    d3=Demo()
    print(id(d1))
    print(id(d2))
    print(id(d3))

开始执行
2545623642016
2545623642016
2545623642016

2、用类装饰器实现

class Person:
    obj={}
    def __init__(self,func):
        self.func=func

    def __call__(self, *args, **kwargs):
        if self.func not in self.obj:
            self.obj[self.func]=self.func(*args,**kwargs)
            return self.obj[self.func]
        else:
            return self.obj[self.func]

@Person                 #Demo=Person(Demo)
class Demo:
    print('开始执行')

if __name__ == '__main__':
    d1=Demo()
    d2=Demo()
    d3=Demo()
    print(d1)
    print(d2)
    print(d3)

开始执行
<main.Demo object at 0x000001F0B6802F70>
<main.Demo object at 0x000001F0B6802F70>
<main.Demo object at 0x000001F0B6802F70>

案例三:请实现一个类,前五次创建对象,每次都可以返回一个新的对象,第六次开始,每次创建,都随机返回前5个对象中的一个

import random
class Person:
    obj_list=[]

    def __new__(cls, *args, **kwargs):
        if len(cls.obj_list) < 5:
            cls.obj=super().__new__(cls)
            cls.obj_list.append(cls.obj)

            return cls.obj
        else:
            return random.choice(cls.obj_list)

if __name__ == '__main__':
    p=Person()
    p1=Person()
    p2=Person()
    p3=Person()
    p4=Person()
    p5=Person()
    p6=Person()
    print(id(p))
    print(id(p1))
    print(id(p2))
    print(id(p3))
    print(id(p4))
    print(id(p5))
    print(id(p6))


物联沃分享整理
物联沃-IOTWORD物联网 » python – 单例模式

发表评论