python中如何实现单例模式

python中实现Singleton模式

主要参考来自于stackoverflow

方法一:装饰器decorator

1
2
3
4
5
6
7
8
9
10
11
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
@singleton
class MyClass:
...

这个例子来自PEP 318 - Decorators for Functions and Methods

方法二:基类Base class

1
2
3
4
5
6
7
8
9
class Singleton(object):
_instance = None
def __new__(class_, *args, **kwargs):
if not isinstance(class_._instance, class_):
class_._instance = object.__new__(class_, *args, **kwargs)
return class_._instance
class MyClass(Singleton, BaseClass):
pass

方法三:元类metaclass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
#Python2
class MyClass(BaseClass):
__metaclass__ = Singleton
#Python3
class MyClass(BaseClass, metaclass=Singleton):
pass

方法四:用装饰器返回一个相同名字的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def singleton(class_):
class class_w(class_):
_instance = None
def __new__(class_, *args, **kwargs):
if class_w._instance is None:
class_w._instance = super(class_w,
class_).__new__(class_,
*args,
**kwargs)
class_w._instance._sealed = False
return class_w._instance
def __init__(self, *args, **kwargs):
if self._sealed:
return
super(class_w, self).__init__(*args, **kwargs)
self._sealed = True
class_w.__name__ = class_.__name__
return class_w
@singleton
class MyClass(BaseClass):
pass

其他的思考

1、利用模块来代替单例的实现,将模块看成一个Singleton,直接在里面定义方法,参考这里
这可能是the most idiomatic way。

2、Borg(共享)模式

1
2
3
4
5
class Borg:
__shared_state = {}
def __init__(self):
self.__dict__ = self.__shared_state
# and whatever else you want in your class -- that's all!

更多讨论参考这里