400-650-7353

精品课程

您所在的位置:首页 > IT干货资料 > python > 【Python基础知识】单例模式

【Python基础知识】单例模式

单例模式是保证一个类仅有一个实例的设计模式。Windows中的任务管理器就是一个典型的单例模式软件。Windows任务管理器如图所示。

Windows任务管理器

Windows任务管理器只能打开一个,即使用户重复打开,也只能获得一个实例,这不同于Word等软件可以打开多个实例。这是因为如果有2个窗口同时都能结束进程,那么在窗口A中结束了某进程,而在窗口B中该进程还保留着;反之,在窗口B中结束了某进程,而在窗口A中该进程还保留着。这样就会造成冲突,导致系统崩溃。

定义单例类的语法格式如下:

class 类名(object):

def __new__(cls, *args, **kwargs):

if not hasattr(cls, '_instance'):

# 第一种方式

cls._instance = object.__new__(cls)

# 第二种方式

# cls._instance = super(类名, cls).__new__(cls)

return cls._instance

创建的单例类继承了object类。类中定义了一个魔法方法__new__(),__new__()方法是创建实例时调用的方法,因此,常说的创建一个实例,其实就是使用这个方法创建的。在__new__()方法中,第一个参数为cls,说明这是一个类方法,后面两个参数分别为*args和**kwargs。用这个方法来创建唯一实例。__new__()方法中,采用if语句判断当前类的实例是否存在,如果不存在,那么需要先创建实例,再返回当前类的实例;如果存在,那么直接返回当前类的实例。可以采用两种方式来创建实例,第一种方式是父类object调用魔法方法__new__(),参数为当前类本身;第二种是用super()方法,指定调用当前类父类的__new__()方法。

【Python基础知识】单例模式

下面是一个单例类的示例。先编写一个Singleton类,代码如下:

  1. class Singleton(object): 
  2.     def __new__(cls, *args, **kwargs): 
  3.         if not hasattr(cls'_instance'): 
  4.             cls._instance = object.__new__(cls
  5.             # cls._instance = super(Singleton, cls).__new__(cls) 
  6.         return cls._instance 

再创建Singleton类的两个实例,代码如下:

  1. s1 = Singleton() 
  2. s2 = Singleton() 

最后通过id()函数生成两个实例的内存地址,从而判断Singleton类是不是单例类,代码如下:

  1. print('s1的地址:{},s2的地址:{}'.format(id(s1), id(s2))) 

运行结果:

  1. s1的地址:31244920,s2的地址:31244920 

由运行结果可知,这两个实例的内存地址一致,说明是同一个实例,即生成的是单一实例,也就是说s1和s2其实是这一个实例的不同名称而已,因此,Singleton类是单例类。

在上述示例的基础上,先创建一个Mother类继承Singleton类,类中包含实例属性msg表示菜信息,实例方法get_food()用于接收并拼接菜信息msg,实例方法food()用于打印菜信息msg:

  1. class Mother(Singleton):   # 继承Singleton类 
  2.     def __init__(self, msg=''): 
  3.         self.msg = msg 
  4.     def get_food(self, new_food): 
  5.         self.msg += new_food 
  6.     def food(self): 
  7.         print('做菜:'self.msg) 

再创建Mother类的两个实例,并分别调用get_food()方法将菜信息作为参数进行传递,代码如下:

  1. mother1 = Mother() 
  2. mother2 = Mother() 
  3. mother1.get_food('西红柿'
  4. mother2.get_food('鸡蛋'

最后分别打印这两个实例的内存地址,并调用food()方法打印菜信息,代码如下:

  1. print('儿子的妈妈id:', id(mother1)) 
  2. mother1.food() 
  3. print('女儿的妈妈id:', id(mother2)) 
  4. mother2.food() 

运行结果:

  1. 儿子的妈妈id: 5758896 
  2. 做菜: 西红柿鸡蛋 
  3. 女儿的妈妈id: 5758896 
  4. 做菜: 西红柿鸡蛋 

由于Monther类继承了Singleton类,因此,实例mother1和mother2指向的是同一个内存地址,两次调用get_food()方法,参数中的字符串会拼接在一起,在调用food()方法时,打印结果都是拼接后的“西红柿鸡蛋”。

如果在创建Mother类时不继承Singleton类,那么运行结果是否发生改变呢?只修改定义Mother类的第一行代码,其余代码不变,修改的代码如下:

  1. class Mother(): 

运行结果:

  1. 儿子的妈妈id: 169246848 
  2. 做菜: 西红柿 
  3. 女儿的妈妈id: 169246904 
  4. 做菜: 鸡蛋 

由两次的运行结果可知,修改之前打印的两个内存地址是相同的,而修改之后打印的两个内存地址不相同,说明修改之后创建Monther类的两个实例是不同的实例,因此,这两个实例分别调用get_food()方法时,字符串不会进行拼接,调用food()方法时打印结果也不相同。

综上所述,单例模式只有唯一实例,解决资源共享问题,节约系统内存,提高系统运行效率。

课程好礼申请领取
您的姓名
您的电话
意向课程
 

中公优就业

官方QQ

扫描上方二维码或点击一键加群,免费领取价值599元网课,加群暗号:599。 一键加群

>>本文地址:
注:本站稿件未经许可不得转载,转载请保留出处及源文件地址。

推荐阅读

测一测
你适合学哪门IT技术?

1 您的年龄

2 您的学历

3 您更想做哪个方向的工作?

获取测试结果
 
课程资料、活动优惠 领取通道
 
 
网站地图 500w彩票网注册 五星彩票网网站 快乐彩票官网
沙龙国际网上娱乐 申博管理登入 大型电玩游戏 申博太阳城娱乐官网
山东群英会山东11选5 澳门金沙网上娱乐 澳门威尼斯人酒店登入 名仕亚洲登入
500w彩票网游戏 500万彩票网即时比分 500w彩票注册 500w彩票网客户端下载
彩29彩票网注册 快乐彩票平台 彩29彩票app下载 58彩票网注册
898cw.com 958sj.com 132sun.com 8NCS.COM 596ib.com
8PJS.COM 789XTD.COM XSB593.COM 1112997.COM 66TGP.COM
218sunbet.com 22TGP.COM 789XTD.COM 588xsb.com 132cw.com
aj138.com XSB592.COM 188TGP.COM 444BBIN.COM 979sj.com