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 中实现单例模式的一种常见方法。