资讯专栏INFORMATION COLUMN

Python下的设计模式总结----创建型设计模式(一)

lewif / 1715人阅读

摘要:最近在学习设计模式而开发的语言中比较中意的就是了在这里总结下设计模式一般分为三大类构造型结构型行为型先从创建型设计模式开始创建型设计模式包括单例模式抽象工厂模式工厂方法模式生成器模式惰性初始化模式对象池模式原型模式单例模式单例模式的定义是保

最近在学习设计模式,而开发的语言中比较中意的就是python了,在这里总结下.

设计模式一般分为三大类:构造型,结构型,行为型

先从创建型设计模式开始,创建型设计模式包括:单例模式,抽象工厂模式,工厂方法模式,生成器模式,惰性初始化模式,对象池模式,原型模式.

单例模式

单例模式的定义是:保证一个类仅有一个实例,并提供一个它的全局访问点.
先来看看14年前(没写错)的前辈介绍的单例模式例程

</>复制代码

  1. from __future__ import print_function
  2. class Borg:
  3. __shared_state = {}
  4. def __init__(self):
  5. self.__dict__ = self.__shared_state
  6. self.state = "Init"
  7. def __str__(self):
  8. return self.state
  9. class YourBorg(Borg):
  10. pass
  11. if __name__ == "__main__":
  12. rm1 = Borg()
  13. rm2 = Borg()
  14. rm1.state = "Idle"
  15. rm2.state = "Running"
  16. print("rm1:{0}".format(rm1))
  17. print("rm2:{0}".format(rm2))
  18. rm2.state = "Zombie"
  19. print("rm1:{0}".format(rm1))
  20. print("rm2:{0}".format(rm2))
  21. print("rm1 id:{0}".format(id(rm1)))
  22. print("rm2 id:{0}".format(id(rm2)))
  23. rm3 = YourBorg()
  24. print("rm1:{0}".format(rm1))
  25. print("rm2:{0}".format(rm2))
  26. print("rm3:{0}".format(rm3))
  27. # Output
  28. # rm1:Running
  29. # rm2:Running
  30. # rm1:Zombie
  31. # rm2:Zombie
  32. # rm1 id:140609170593696
  33. # rm2 id:140609170593624
  34. # rm1:Init
  35. # rm2:Init
  36. # rm3:Init

简单解释下,需要get的点是下面这段代码

</>复制代码

  1. __shared_state = {}
  2. def __init__(self):
  3. self.__dict__ = self.__shared_state
  4. self.state = "Init"

self.__dict__是对象的字典表示.将对象的属性设为全局静态变量.
根据输出结果,rm1和rm2俨然是一个实例.然而打印出来的rm1,rm2的变量id是不一致的,所以rm1,rm2并不是同一个实例.但是却有同样的状态和行为.但从结果上来看,确实实现了单例模式的要求.(虽然有种走捷径的感觉)

下面看看另一个版本的,其实就是换个形式,原理还是建多个实例,表现一致.其他部分的代码和上面的一致.

</>复制代码

  1. class Borg(object):
  2. __state = {}
  3. def __new__(cls, *p, **k):
  4. self = object.__new__(cls, *p, **k)
  5. self.__dict__ = cls.__state
  6. return self
  7. def __init__(self):
  8. self.state = "Init"

单例模式的创建有很多种方式.
这里有讨论链接描述

升级版,通过__metaclass__实现.这个版本中同一个id说明是同一个对象.

</>复制代码

  1. class Singleton(type):
  2. def __init__(self, name, bases, dict):
  3. super(Singleton, self).__init__(name, bases, dict)
  4. self._instance = None
  5. def __call__(self, *args, **kw):
  6. if self._instance is None:
  7. self._instance = super(Singleton, self).__call__(*args, **kw)
  8. return self._instance
  9. class MyClass(object):
  10. __metaclass__ = Singleton
  11. one = MyClass()
  12. two = MyClass()
  13. two.a = 3
  14. print one.a
  15. # 3
  16. print id(one)
  17. # 139798461922256
  18. print id(two)
  19. # 139798461922256
  20. print one == two
  21. # True
  22. print one is two
  23. # True

还可以通过装饰器来实现.这是第一个方法的高级版本,更pythonic,更elegant的方法.
这个例子中,单例类本身不知道自己是单例的,应为他本身(自己的代码)就不是单例的.

</>复制代码

  1. def singleton(cls, *args, **kw):
  2. instances = {}
  3. def _singleton():
  4. if cls not in instances:
  5. instances[cls] = cls(*args, **kw)
  6. return instances[cls]
  7. return _singleton
  8. @singleton
  9. class MyClass(object):
  10. a = 1
  11. def __init__(self, x=0):
  12. self.x = x
  13. one = MyClass()
  14. two = MyClass()
  15. two.a = 3
  16. print one.a
  17. # 3
  18. print id(one)
  19. # 140630714076048
  20. print id(two)
  21. # 140630714076048
  22. print one == two
  23. # True
  24. print one is two
  25. # True
  26. one.x = 1
  27. print one.x
  28. # 1
  29. print two.x
  30. # 1

好东西留到最后,来个超级无敌版的

</>复制代码

  1. class Singleton:
  2. """
  3. A non-thread-safe helper class to ease Implementing singletons.
  4. This should be used as a decorator -- not a metaclass -- to the
  5. class that should be singleton.
  6. The decorated class can define one `__init__` function that
  7. takes onelythe `self` argument. Other than that, there are no
  8. restrictions that apply to the decorated class.
  9. To get the singleton instances, use the `instances` method. Trying
  10. to use `__call__` will result in a `TypeError` being raised.
  11. Limitations: The decorated class cannot be inherited from.
  12. """
  13. def __init__(self, decorated):
  14. self._decorated = decorated
  15. def instance(self):
  16. """
  17. Return the singleton instance. Upon this first call, it creates
  18. a new instance of decorated class and calls its `__init__` method.
  19. On all subsequent calls, the already created instance is returned.
  20. """
  21. try:
  22. return self._instance
  23. except AttributeError:
  24. self._instance = self._decorated()
  25. return self._instance
  26. def __call__(self):
  27. raise TypeError("Singletons must be accessed through `instance()`.")
  28. def __instancecheck(self, inst):
  29. return isinstance(inst, self._decorated)
  30. @Singleton
  31. class Foo:
  32. def __init__(self):
  33. print "Foo created"
  34. # f = Foo()
  35. # TypeError: Singletons must be accessed through `instance()`.
  36. f = Foo.instance()
  37. g = Foo.instance()
  38. # Foo created
  39. print f is g
  40. # 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

相关文章

  • J2EE下的常用设计模式

    摘要:当然,除了让我们显得更加专业之外,在自己所学习或者工作的项目中,适当合理的使用设计模式,能够给项目带来很大的好处。 简单说两句 本文首发公众号【一名打字员】 对不住各位老铁了,年前说好要更几波JAVA的东西,又偷懒了,没办法,在这里用小锤锤偷偷锤了自己几下。由于工作原因,更新时间不定,各位老铁有问题可以私聊我哈。 对于初学者或者是正在向中高级的Java程序猿(打字员)来说,时刻梳理自己...

    robin 评论0 收藏0
  • Java开发

    摘要:大多数待遇丰厚的开发职位都要求开发者精通多线程技术并且有丰富的程序开发调试优化经验,所以线程相关的问题在面试中经常会被提到。将对象编码为字节流称之为序列化,反之将字节流重建成对象称之为反序列化。 JVM 内存溢出实例 - 实战 JVM(二) 介绍 JVM 内存溢出产生情况分析 Java - 注解详解 详细介绍 Java 注解的使用,有利于学习编译时注解 Java 程序员快速上手 Kot...

    LuDongWei 评论0 收藏0
  • 7天学会3门语言,第

    摘要:天入门三门编程语言,有可能嘛,尤其是对没有基础的同学来说对于想学好的编程的人来说,无论从哪一门语言开始入手,语言的本身其实并不是我们最应该的关心的,至少不是作为一个初学者首先关心的。 7天入门三门编程语言,有可能嘛,尤其是对没有基础的同学来说?对于想学好的编程的人来说,无论从哪一门语言开始入手,语言的本身其实并不是我们最应该的关心的,至少不是作为一个初学者首先关心的。 网络上,网友们争...

    aristark 评论0 收藏0
  • 7天学会3门语言,第

    摘要:天入门三门编程语言,有可能嘛,尤其是对没有基础的同学来说对于想学好的编程的人来说,无论从哪一门语言开始入手,语言的本身其实并不是我们最应该的关心的,至少不是作为一个初学者首先关心的。 7天入门三门编程语言,有可能嘛,尤其是对没有基础的同学来说?对于想学好的编程的人来说,无论从哪一门语言开始入手,语言的本身其实并不是我们最应该的关心的,至少不是作为一个初学者首先关心的。 网络上,网友们争...

    RebeccaZhong 评论0 收藏0

发表评论

0条评论

lewif

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<