凉城旧巷
Python从入门到自闭,Java从自闭到放弃,数据库从删库到跑路,Linux从rm -rf到完犊子!!!
posts - 315,comments - 20,views - 38万

单例模式

一、什么是单例

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

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

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

复制代码

 

posted on   凉城旧巷  阅读(139)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示