四种 python 实现的单例模式的方式

  1. 使用 __new__ 方法
    1. 代码
    2. 测试
  2. 使用共享属性
    1. 代码
    2. 测试
  3. 使用元类
    1. 代码
    2. 测试
  4. 使用装饰器
    1. 代码
    2. 测试

单例模式是一个非常常见的设计模式,

使用 __new__ 方法

new方法必须要返回一个实例化的对象

代码
1
2
3
4
5
6
7
8
9
10
11
class Singleton(object):

def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
cls._instance = super().__new__(cls, *args, **kwargs)

return cls._instance


class Test(Singleton):
a = 1
测试
1
2
3
4
In [6]: a, b = Test(), Test()

In [7]: print(id(a), id(b))
139990582602440 139990582602440

使用共享属性

所谓单例就是所有引用(实例、对象)拥有相同的状态(属性)和行为(方法), 同一个类的所有实例天然拥有相同的行为(方法),只需要保证同一个类的所有实例具有相同的状态(属性)即可,所有实例共享属性的最简单最直接的方法就是使 __dict__属性指向(引用)同一个字典(dict)

代码
1
2
3
4
5
6
7
8
9
10
11
class Singleton(object):
_state = {}

def __new__(cls, *args, **kwargs):
ob = super().__new__(cls, *args, **kwargs)
ob.__dict__ = cls._state
return ob


class Test(Singleton):
a = 1
测试
1
2
3
4
5
6
7
In [9]: a, b = Test(), Test()

In [10]: print(a.__dict__)
{}

In [11]: print(id(a.__dict__), id(b.__dict__))
139872953600760 139872953600760

使用元类

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
class Singleton(type):
def __init__(cls, name, bases, dict):
super(Singleton, cls).__init__(name, bases, dict)
cls._instance = None

def __call__(cls, *args, **kw):
if cls._instance is None:
cls._instance = super(Singleton, cls).__call__(*args, **kw) # 这句你怎么理解?
return cls._instance


class Test(metaclass=Singleton):
a = 1
测试
1
2
3
4
In [7]: a, b = Test(), Test()

In [8]: print(id(a), id(b))
139856176187376 139856176187376

使用装饰器

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def singleton(cls, *args, **kw):

instances = {}

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

return _singleton


@singleton
class Test(object):
a = 1
测试
1
2
3
4
In [2]: a, b = Test(), Test()

In [3]: print(id(a), id(b))
140717732304656 140717732304656

文章标题:四种 python 实现的单例模式的方式

文章字数:399

本文作者:Waterandair

发布时间:2018-05-22, 09:24:06

最后更新:2019-12-28, 14:03:59

原始链接:https://waterandair.github.io/2018-05-22-python-singleton.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

github