Python单例模式几种实现

注明事项

本文中示例来自:[Python] 实现单例模式的四种方式及单例模式日志,主要记录学习该篇博客过程。

1. 使用__new__实现单例模式

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

print(Singleton() is Singleton())   # True
class Singleton(object):
这是一个定义类的语句,它定义了一个名为 Singleton 的类。这个类在本例中被用来创建单例对象。

def __new__(cls, *args, **kwargs):
这是一个特殊方法,用于在对象创建之前被调用。__new__ 方法的作用是创建并返回一个新的实例。在这个例子中,我们会在这个方法中实现单例的逻辑。

if not hasattr(cls, "_instance"):
这行代码使用 hasattr() 函数检查类是否已经具有 _instance 属性。如果类没有 _instance 属性,表示尚未创建实例。

cls._instance = super().__new__(cls, *args, **kwargs)
如果类没有实例,这行代码将通过调用父类的 __new__ 方法创建一个新实例,并将其存储在 _instance 属性中。这里使用 super() 来调用父类的 __new__ 方法。

return cls._instance
无论是之前已经存在实例,还是刚刚创建了实例,都会返回存储在 _instance 属性中的实例。这就确保了同一个类的不同实例都指向相同的实际对象,从而实现了单例模式。

这段代码通过在 __new__ 方法中管理实例的创建,确保了一个类只有一个实例存在。

2. 使用__call__方法实现单例模式

class SingletonType(type):
    _instances = {}
    
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(SingletonType, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class A(metaclass=SingletonType):
    pass

print(A() is A())   # True
class SingletonType(type):
这是一个定义元类的类。它继承自内置的 type 类,这意味着 SingletonType 是一个元类。

_instances = {}
这是一个类属性,用于存储每个类的唯一实例。这个字典将类映射到它们的实例。

def __call__(cls, *args, **kwargs):
这是元类的特殊方法,它会在创建类的实例时被调用。cls 参数表示类本身,args 和 kwargs 是传递给类构造函数的参数。

if cls not in cls._instances:
这行代码检查给定类是否已经有一个实例。如果该类不在 _instances 字典中,表示该类还没有被实例化过。

cls._instances[cls] = super(SingletonType, cls).__call__(*args, **kwargs)
如果类尚未实例化,这行代码会调用父类的 __call__ 方法来创建一个新的实例,并将这个实例存储到 _instances 字典中,以类为键。

return cls._instances[cls]
无论是之前已经有实例,还是刚刚创建了新实例,都会返回该类的实例。这保证了无论何时创建类的实例,都只会得到同一个实例。

通过将元类 SingletonType 分配给类,该类就会变成一个单例类。这意味着每次实例化这个类时,都会返回相同的实例,从而实现了单例模式的效果。

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
def singleton(cls):
这是一个函数定义,它定义了一个名为 singleton 的装饰器函数。这个装饰器函数将被用来将类转换为单例模式。

instances = {}
在 singleton 函数内部,定义了一个字典 instances,用于存储每个类的唯一实例。

def _singleton(*args, **kwargs):
在 singleton 函数内部,定义了一个嵌套函数 _singleton,这个函数将取代原始的类构造函数。它接受任意数量的位置参数 args 和关键字参数 kwargs。

if cls not in instances:
这行代码检查给定的类 cls 是否已经在 instances 字典中有实例。如果没有,表示该类还没有被实例化过。

instances[cls] = cls(*args, **kwargs)
如果类尚未实例化,这行代码会通过调用原始的类构造函数 cls(*args, **kwargs) 创建一个新的实例,并将这个实例存储到 instances 字典中。

return instances[cls]
无论是之前已经存在实例,还是刚刚创建了新实例,都会返回存储在 instances 字典中的实例。这就确保了同一个类的不同实例都指向相同的实际对象,从而实现了单例模式。

@singleton
这是装饰器的用法,它将被应用到下面的类定义中。在这个例子中,装饰器将类 A 转换为单例模式。

class A:
这是一个类定义。通过应用装饰器 @singleton,这个类变成了单例类。无论多少次实例化类 A,都只会得到同一个实例。

这段代码通过装饰器函数 singleton,将一个类转换为单例模式。这种方式更加简洁,易于理解和使用。这是 Python 中实现单例模式的一种常见方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值