python单例模式实现

本文详细介绍了Python中实现单例模式的四种常见方法:使用__new__方法、元类的__call__方法、装饰器以及利用模块特性。每种方法的示例代码清晰展示了如何确保类在多次调用时只产生一个实例,并讨论了其应用场景和效果。通过这些方法,可以更好地理解和应用单例模式。
摘要由CSDN通过智能技术生成

0.单例介绍

在使用类创建对象的时候,每次都会调用__new__()方法创建一个新的对象并调用__init__()方法对实例对象进行初始化,单例模式即不管创建了多少次,都只产生唯一的实例对象。可以在调用new方法前验证是否之前创建过实例对象,如果创建过则返回该对象

1.使用__new__()方法创建单例

class Singleton(object):

    def __init__(self):
        pass

    def __new__(cls, *args, **kwargs):
        # hasatter() 判断一个对象是否有某个属性
        if not hasattr(cls, "_instance"):   
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance

print(Singleton() is Singleton())      # True

 该方式的init初始化可以被覆盖

class Singleton(object):

    def __init__(self,name):
        self.name = name

    def __new__(cls, *args, **kwargs):
        # hasatter() 判断一个对象是否有某个属性
        if not hasattr(cls, "_instance"):   
            cls._instance = super().__new__(cls)
        return cls._instance

a1 = Singleton("zhangsan")
a2 = Singleton("lisi")
print(a1 is a2)      # True
print(a1.name)  # zhangsan
print(a2.name)  # lisi

2.使用元类的__call__()方法

元类(metaclass),只有继承了type的类才可以作为元类被继承,所有的用户定义类,都是type类的实例(ps:object是type类的实例,同时也是type的基类)。

# 正常定义类
class MyClass:
  data = 1

# Python 真正执行的是下面这段代码:
class = type(classname, superclasses, attributedict)

# 这里等号右边的type(classname, superclasses, attributedict),就是 type 的__call__运算符重载,它会进一步调用:
type.__new__(typeclass, classname, superclasses, attributedict)
type.__init__(class, classname, superclasses, attributedict)

因此可以创建一个单例元类,想要实现单例的类直接继承该元类

class Singleton(type):
    _instace = {}


    def __call__(cls, *args, **kwargs):
        if cls not in cls._instace:
            cls._instace[cls] = super().__call__(*args, **kwargs)
        return cls._instace[cls]


class A(metaclass=Singleton):
    def __init__(self,name):
        self.name = name

a1 = A("zhangsan")
a2 = A("lisi")
print(a1 is a2)  # True
print(a1.name)  # zhangsan
print(a2.name)  # zhangsan

3.使用装饰器

def singleton(cls):
    instances = {}

    def _singleton(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return _singleton

@singleton
class A:
    pass

print(A() is A())   # True

4.模块单例

Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。

# single.py
class Singleton: 
	pass

singleton = Singleton()


# other.py
from single import singleton

转载自:https://blog.csdn.net/Spade_/article/details/108425896

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值