最近在学习设计模式,而开发的语言中比较中意的就是python了,在这里总结下.
设计模式一般分为三大类:构造型,结构型,行为型
先从创建型设计模式开始,创建型设计模式包括:单例模式,抽象工厂模式,工厂方法模式,生成器模式,惰性初始化模式,对象池模式,原型模式.
单例模式
单例模式的定义是:保证一个类仅有一个实例,并提供一个它的全局访问点.
先来看看14年前(没写错)的前辈介绍的单例模式例程
from __future__ import print_function
class Borg:
__shared_state = {}
def __init__(self):
self.__dict__ = self.__shared_state
self.state = "Init"
def __str__(self):
return self.state
class YourBorg(Borg):
pass
if __name__ == '__main__':
rm1 = Borg()
rm2 = Borg()
rm1.state = 'Idle'
rm2.state = "Running"
print('rm1:{0}'.format(rm1))
print('rm2:{0}'.format(rm2))
rm2.state = 'Zombie'
print('rm1:{0}'.format(rm1))
print('rm2:{0}'.format(rm2))
print('rm1 id:{0}'.format(id(rm1)))
print('rm2 id:{0}'.format(id(rm2)))
rm3 = YourBorg()
print('rm1:{0}'.format(rm1))
print('rm2:{0}'.format(rm2))
print('rm3:{0}'.format(rm3))
# Output
# rm1:Running
# rm2:Running
# rm1:Zombie
# rm2:Zombie
# rm1 id:140609170593696
# rm2 id:140609170593624
# rm1:Init
# rm2:Init
# rm3:Init
简单解释下,需要get的点是下面这段代码
__shared_state = {}
def __init__(self):
self.__dict__ = self.__shared_state
self.state = "Init"
self.__dict__是对象的字典表示.将对象的属性设为全局静态变量.
根据输出结果,rm1和rm2俨然是一个实例.然而打印出来的rm1,rm2的变量id是不一致的,所以rm1,rm2并不是同一个实例.但是却有同样的状态和行为.但从结果上来看,确实实现了单例模式的要求.(虽然有种走捷径的感觉)
下面看看另一个版本的,其实就是换个形式,原理还是建多个实例,表现一致.其他部分的代码和上面的一致.
class Borg(object):
__state = {}
def __new__(cls, *p, **k):
self = object.__new__(cls, *p, **k)
self.__dict__ = cls.__state
return self
def __init__(self):
self.state = "Init"
单例模式的创建有很多种方式.
这里有讨论链接描述
升级版,通过__metaclass__实现.这个版本中同一个id说明是同一个对象.
class Singleton(type):
def __init__(self, name, bases, dict):
super(Singleton, self).__init__(name, bases, dict)
self._instance = None
def __call__(self, *args, **kw):
if self._instance is None:
self._instance = super(Singleton, self).__call__(*args, **kw)
return self._instance
class MyClass(object):
__metaclass__ = Singleton
one = MyClass()
two = MyClass()
two.a = 3
print one.a
# 3
print id(one)
# 139798461922256
print id(two)
# 139798461922256
print one == two
# True
print one is two
# True
还可以通过装饰器来实现.这是第一个方法的高级版本,更pythonic,更elegant的方法.
这个例子中,单例类本身不知道自己是单例的,应为他本身(自己的代码)就不是单例的.
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 MyClass(object):
a = 1
def __init__(self, x=0):
self.x = x
one = MyClass()
two = MyClass()
two.a = 3
print one.a
# 3
print id(one)
# 140630714076048
print id(two)
# 140630714076048
print one == two
# True
print one is two
# True
one.x = 1
print one.x
# 1
print two.x
# 1
好东西留到最后,来个超级无敌版的
class Singleton:
"""
A non-thread-safe helper class to ease Implementing singletons.
This should be used as a decorator -- not a metaclass -- to the
class that should be singleton.
The decorated class can define one `__init__` function that
takes onelythe `self` argument. Other than that, there are no
restrictions that apply to the decorated class.
To get the singleton instances, use the `instances` method. Trying
to use `__call__` will result in a `TypeError` being raised.
Limitations: The decorated class cannot be inherited from.
"""
def __init__(self, decorated):
self._decorated = decorated
def instance(self):
"""
Return the singleton instance. Upon this first call, it creates
a new instance of decorated class and calls its `__init__` method.
On all subsequent calls, the already created instance is returned.
"""
try:
return self._instance
except AttributeError:
self._instance = self._decorated()
return self._instance
def __call__(self):
raise TypeError('Singletons must be accessed through `instance()`.')
def __instancecheck(self, inst):
return isinstance(inst, self._decorated)
@Singleton
class Foo:
def __init__(self):
print "Foo created"
# f = Foo()
# TypeError: Singletons must be accessed through `instance()`.
f = Foo.instance()
g = Foo.instance()
# Foo created
print f is g
# True
关于python的单例模式,各家说法不一.可以根据不同的需求,使用不同的方式,适合的才是最好的.
参考文字:
https://zh.wikipedia.org/wiki/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F_(%E8%AE%A1%E7%AE%97%E6%9C%BA)
http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/
http://code.activestate.com/recipes/66531/
http://blog.csdn.net/ghostfromheaven/article/details/7671853
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。