python——单例模式

本文介绍了Python中的单例模式,包括手动实现单例、使用装饰器实现单例,以及一个特殊需求的单例类实现,即前五次创建返回新对象,之后随机返回前五个之一。同时阐述了单例模式在日志收集器、数据库连接等场景下的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

单例模式使用场景:

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))

在这里插入图片描述


在这里插入图片描述

评论 48
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码敲到头发茂密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值