python单例模式继承_python单例模式

单例模式是常见的一种设计模式,它是针对类的一种描述,因此,我们可以使用python的decorator来实现通用的单例模式。

一.基本的单例模式

首先建立我们的decorator。我们需要为classType建立_instance和_lock成员:

Python

def singleton(classType):

classType._instance = None

classType._lock = Lock()

return classType

1

2

3

4

defsingleton(classType):

classType._instance=None

classType._lock=Lock()

returnclassType

然后为class建立getInstance函数:

Python

def __getInstance(classname):

if classname._instance is None:

classname._lock.acquire()

if classname._instance is None:

classname._instance = classname()

classname._lock.release()

return classname._instance

1

2

3

4

5

6

7

def__getInstance(classname):

ifclassname._instanceisNone:

classname._lock.acquire()

ifclassname._instanceisNone:

classname._instance=classname()

classname._lock.release()

returnclassname._instance

然后在我们的decorator中,将getInstance函数添加到class上:

Python

classType.getInstance = classmethod(__getInstance)

1

classType.getInstance=classmethod(__getInstance)

现在我们的代码长这样。这个decorator已经具备了基本功能:

Python

def __getInstance(classType):

if classType._instance is None:

classType._lock.acquire()

if classType._instance is None:

classType._instance = classType()

classType._lock.release()

return classType._instance

def singleton(classType):

classType._instance = None

classType._lock = Lock()

classType.getInstance = classmethod(__getInstance)

return classType

1

2

3

4

5

6

7

8

9

10

11

12

13

def__getInstance(classType):

ifclassType._instanceisNone:

classType._lock.acquire()

ifclassType._instanceisNone:

classType._instance=classType()

classType._lock.release()

returnclassType._instance

defsingleton(classType):

classType._instance=None

classType._lock=Lock()

classType.getInstance=classmethod(__getInstance)

returnclassType

使用方法如下:

Python

@singleton

class XXX(object):

# add class definitions

pass

1

2

3

4

@singleton

classXXX(object):

# add class definitions

pass

二.可继承的单例模式

现在让我们为这个单例模式添加一些功能:我们让被这个单例类可以产生子类,且子类也是单例类,和父类共享同一个instance。为此,我们必须修改被修饰的单例类的init方法,在其中设置instance为自身:

Python

def __singleton_init(self):

# check whether instance has existed

if self._instance is not None:

raise SingletonExistedError(type(self))

# set instance of this class and its ancestor classes to self

for baseClass in inspect.getmro(type(self)):

if '_instance' in baseClass.__dict__:

baseClass._instance = self

1

2

3

4

5

6

7

8

9

def__singleton_init(self):

# check whether instance has existed

ifself._instanceisnotNone:

raiseSingletonExistedError(type(self))

# set instance of this class and its ancestor classes to self

forbaseClassininspect.getmro(type(self)):

if'_instance'inbaseClass.__dict__:

baseClass._instance=self

SingletonExistedError为自定义的error类型:

Python

class SingletonExistedError(Exception):

def __init__(self, classType):

super(SingletonExistedError, self).__init__('trying to construct instance of singleton class ' + classType.__name__ + ' while an instance has already existed!')

1

2

3

classSingletonExistedError(Exception):

def__init__(self,classType):

super(SingletonExistedError,self).__init__('trying to construct instance of singleton class '+classType.__name__+' while an instance has already existed!')

现在我们需要把这个新的init函数添加到被修饰的单例类的init函数上。很自然的,我们又可以利用函数的decorator来办成这件事情,就像这样:

Python

def __singleton_init_decorator(init_func):

def __singleton_init(self):

# check whether instance has existed

if self._instance is not None:

raise SingletonExistedError(type(self))

# set instance of the class and ancestor singletons to self

for baseClass in inspect.getmro(type(self)):

if '_instance' in baseClass.__dict__:

baseClass._instance = self

init_func(self)

return __singleton_init

1

2

3

4

5

6

7

8

9

10

11

12

13

def__singleton_init_decorator(init_func):

def__singleton_init(self):

# check whether instance has existed

ifself._instanceisnotNone:

raiseSingletonExistedError(type(self))

# set instance of the class and ancestor singletons to self

forbaseClassininspect.getmro(type(self)):

if'_instance'inbaseClass.__dict__:

baseClass._instance=self

init_func(self)

return__singleton_init

最后,在我们的singleton decorator上加上这句代码:

Python

classType.__init__ = __singleton_init_decorator(classType.__init__)

1

classType.__init__=__singleton_init_decorator(classType.__init__)

大功告成!附上完整代码:

Python

class SingletonExistedError(Exception):

def __init__(self, classType):

super(SingletonExistedError, self).__init__('trying to construct instance of singleton class ' + classType.__name__ + ' while an instance has already existed!')

def __getInstance(classType):

if classType._instance is None:

classType._lock.acquire()

if classType._instance is None:

classType._instance = classType()

classType._lock.release()

return classType._instance

def __singleton_init_decorator(init_func):

def __singleton_init(self):

# check whether instance has existed

if self._instance is not None:

raise SingletonExistedError(type(self))

# set instance of the class and ancestor singletons to self

for baseClass in inspect.getmro(type(self)):

if '_instance' in baseClass.__dict__:

baseClass._instance = self

init_func(self)

return __singleton_init

def singleton(classType):

classType._instance = None

classType._lock = Lock()

classType.getInstance = classmethod(__getInstance)

classType.__init__ = __singleton_init_decorator(classType.__init__)

return classType

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

classSingletonExistedError(Exception):

def__init__(self,classType):

super(SingletonExistedError,self).__init__('trying to construct instance of singleton class '+classType.__name__+' while an instance has already existed!')

def__getInstance(classType):

ifclassType._instanceisNone:

classType._lock.acquire()

ifclassType._instanceisNone:

classType._instance=classType()

classType._lock.release()

returnclassType._instance

def__singleton_init_decorator(init_func):

def__singleton_init(self):

# check whether instance has existed

ifself._instanceisnotNone:

raiseSingletonExistedError(type(self))

# set instance of the class and ancestor singletons to self

forbaseClassininspect.getmro(type(self)):

if'_instance'inbaseClass.__dict__:

baseClass._instance=self

init_func(self)

return__singleton_init

defsingleton(classType):

classType._instance=None

classType._lock=Lock()

classType.getInstance=classmethod(__getInstance)

classType.__init__=__singleton_init_decorator(classType.__init__)

returnclassType

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/350123.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[MEGA DEAL]完整的Java编程训练营(94%)

成为Java Master的10门课程(83.5小时):使用JavaFX的设计UI,利用设计模式,Master Multithreading等 嘿,怪胎, 本周,在我们的JCG Deals商店中 ,我们提供了一个极端的报价…

【洛谷 1879】玉米田

题目描述农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ 12; 1 ≤ N ≤ 12),每一格都是一块正方形的土地。John打算在牧场上的某几格里种上美味的草,供他的奶牛们享用。遗憾的是,有些土地相当贫瘠&#xf…

echarts的tree怎么控制位置_自动化考研保研面试—线性系统控制器设计

这个问题是我导师(面试组长)多次在保研考研面试的时候问过的,而且每年都会问!问题其实不难,涉及的知识点也就是自控原理经典控制理论的部分,但是基本上很少有人能够完整地回答出来,不服的话请看…

PCF上的Spring Cloud合同和Spring Cloud Services

最近,我们有一个客户,对于使用Spring Cloud Contract (SCC)来防止微服务团队之间的API“漂移”,微型开发团队需要由单个开发团队来照顾构成企业应用程序一部分的单个API的想法非常感兴趣。 Spring Cloud Contract是Sp…

MS Lync2010客户端开发体会

和前身OCS2007 相比较,Lync2010原生客户端的扩展性大大缩小了,但是提供了很好的客户端SDK,整个系统架构也有较大变化。由于Lync2010原生客户端实在太简单,用惯了QQ的国人,实在无法接受以下功能的缺失: 组织…

date javascript 时区_第23节 Datejs 日期库-Web前端开发之Javascript-零点程序员-王唯

Datejs 是一个开源的JavaScript库,用来解析、格式化和处理日期数据,支持多种语言的日期格式处理;官网:www.datejs.com/Moment.js 是一个简单易用的轻量级JavaScript日期处理类库,提供了日期格式化、日期解析等功能。它…

制杖题

题目描述 求不大于 m 的、 质因数集与给定质数集有交集的自然数之和。 输入格式 第一行二个整数 n,m。 第二行 n 个整数,表示质数集内的元素 p[i]。 输出格式 一个整数,表示答案,对 376544743 取模。 输入输出样例 输入 #1复制 2 …

煤矿安全规程专家解读2016电子版_【学习】煤矿安全规程专家解读(165)

点击蓝字关注我们第二编 井工部分第三百三十三条爆破前,必须加强对机器、液压支架和电缆等的保护或将其移出工作面。爆破前,班组长必须亲自布置专人在警戒线和可能进入爆破地点的所有通路上担任警戒工作。警戒人员必须在安全地点警戒。警戒线处应设置警…

DC / OS中具有Java和数据库应用程序的服务发现

该博客将展示一个简单的Java应用程序如何使用DC / OS中的服务发现与数据库进行对话。 为什么要进行服务发现? 应用程序通常由多个组件组成,例如应用程序服务器,数据库,Web服务器,缓存和消息传递服务器。 通常&#xf…

RAC环境下创建本地数据文件的解决方法

引用收藏:http://blog.itpub.net/501889/viewspace-1083311/ 同事不小心,在RAC环境下创建了本地数据文件,这个肯定会出问题的,节点2不能访问此数据文件。其实发现做错了,立马删掉应该没有问题。数据文件还没有数据。下…

诺基亚n1平板电脑刷机教程_【个人记事本】闲鱼购买平板的经历

今年由于疫情原因,国内开展了全体学生在家学习的模式,这就避免不了老师发一些课件,还有一些录课的视频等电子学习资料等。考虑到开学复习的便利性(平板比笔记本电脑更具有便携性,更方便)。所以,…

找出一个字符串中出现次数最多的字_487,重构字符串

想了解更多数据结构以及算法题,可以关注微信公众号“数据结构和算法”,每天一题为你精彩解答。问题描述给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同。若可行,输出任意可行的结果。若不可行&am…

一、数据设计规范

一、数据设计规范 1、表的前缀 1、表名称不应该取得太长(一般不超过三个英文单词。不推荐使用中文拼音,总的长度不要超过30个字符) 格式:Tbl_Wms_log 表示 表_Wms系统_log 好处:执行查询方式辨别SQL类别(T_表-Table、V_视图-View、S_存储过…

http缓存管理器_小心缓存管理器

http缓存管理器如果使用spring和JPA,则很有可能利用ehcache(或其他缓存提供程序)。 您可以在两种不同的情况下进行此操作:JPA 2级缓存和spring方法缓存。 配置应用程序时,通常会设置JPA提供程序的二级缓存提供程序&am…

cad线加粗怎么设置_AutoCAD2019怎么加粗线条 将不同线段加粗方法

AutoCAD2019是一款非常专业的制图软件,那有很多用户表示自己不知道这款软件怎么加粗线条,下面就通过这篇文章给大家介绍一下,一起往下看吧!如图所示,我用L命令绘制一根线段:,这根线段的宽度为默…

时间管理——你不可不知的3种时间管理方法

时间管理——你不可不知的3种时间管理方法 时间管理 英文名:Time Management   请问,如果每天都有86400元进入你的银行户头,而你必须当天用光,你会如何运用这笔钱?   天下真有这样的好事吗?   是的,…

python tkinter布局混用_[宜配屋]听图阁

这篇文章主要介绍了python tkinter控件布局项目实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下代码部分:from tkinter import *import tkinter.messagebox as messageboxclass Tkdemo():def __i…

ASP.NET中利用ashx实现图片防盗链

盗链的危害我就不说了,网上有很多。 直接分析盗链原理:看下面用httpwatch截获的http发送的数据 GET /Img.ashx?imgsvn_work.gif HTTP/1.1 Accept: */* Referer: http://www.svnhost.cn/ Accept-Language: zh-cn UA-CPU: x86 Accept-Encoding: gzip, def…

适用于Java开发人员的Elasticsearch:Java的Elasticsearch

本文是我们学院课程的一部分,该课程的标题为Java开发人员的Elasticsearch教程 。 在本课程中,我们提供了一系列教程,以便您可以开发自己的基于Elasticsearch的应用程序。 我们涵盖了从安装和操作到Java API集成和报告的广泛主题。 通过我们简…

matlab 日期排序_MATLAB时间序列的排序函数

sort功能:对时间序列x进行排序。格式:m sort(x, mode) % 当参数mode‘ascend’,表示对x进行升序重排;当mode‘descend’,表示降序重排wrev功能:得到时间序列x的逆序。格式:m wrev(x)如>>…