摘要:最近在学习设计模式而开发的语言中比较中意的就是了在这里总结下设计模式一般分为三大类构造型结构型行为型先从创建型设计模式开始创建型设计模式包括单例模式抽象工厂模式工厂方法模式生成器模式惰性初始化模式对象池模式原型模式单例模式单例模式的定义是保
最近在学习设计模式,而开发的语言中比较中意的就是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://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python/31887#31887
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/37691.html
摘要:当然,除了让我们显得更加专业之外,在自己所学习或者工作的项目中,适当合理的使用设计模式,能够给项目带来很大的好处。 简单说两句 本文首发公众号【一名打字员】 对不住各位老铁了,年前说好要更几波JAVA的东西,又偷懒了,没办法,在这里用小锤锤偷偷锤了自己几下。由于工作原因,更新时间不定,各位老铁有问题可以私聊我哈。 对于初学者或者是正在向中高级的Java程序猿(打字员)来说,时刻梳理自己...
摘要:天入门三门编程语言,有可能嘛,尤其是对没有基础的同学来说对于想学好的编程的人来说,无论从哪一门语言开始入手,语言的本身其实并不是我们最应该的关心的,至少不是作为一个初学者首先关心的。 7天入门三门编程语言,有可能嘛,尤其是对没有基础的同学来说?对于想学好的编程的人来说,无论从哪一门语言开始入手,语言的本身其实并不是我们最应该的关心的,至少不是作为一个初学者首先关心的。 网络上,网友们争...
摘要:天入门三门编程语言,有可能嘛,尤其是对没有基础的同学来说对于想学好的编程的人来说,无论从哪一门语言开始入手,语言的本身其实并不是我们最应该的关心的,至少不是作为一个初学者首先关心的。 7天入门三门编程语言,有可能嘛,尤其是对没有基础的同学来说?对于想学好的编程的人来说,无论从哪一门语言开始入手,语言的本身其实并不是我们最应该的关心的,至少不是作为一个初学者首先关心的。 网络上,网友们争...
阅读 1370·2021-11-22 15:11
阅读 2822·2019-08-30 14:16
阅读 2734·2019-08-29 15:21
阅读 2893·2019-08-29 15:11
阅读 2437·2019-08-29 13:19
阅读 2968·2019-08-29 12:25
阅读 399·2019-08-29 12:21
阅读 2793·2019-08-29 11:03