Python 用__new__方法实现单例的操作


Posted in Python onDecember 11, 2020

介绍

init 方法通常用在初始化一个类实例时候,但其实它不是实例化一个类的时候第一个被调用 的方法。当使用 Student(id, name) 这样的表达式来实例化一个类时,最先被调用的方法 其实是 new 方法。

new方法接受的参数虽然也是和init一样,但init是在类实例创建之后调用,而 new方法正是创建这个类实例的方法。

new为对象分配空间,是内置的静态方法,new在内存中为对象分配了空间也返回了对象的引用,init获得了这个引用才初始化这个实例。

示例

一个非常简单的单例

class A:
 instance = None
 def __new__(cls, *args, **kwargs):
  if cls.instance is None:
   cls.instance = super().__new__(cls)
  return cls.instance

因为new方法是一个静态方法(也就是在定义的时候就没有cls参数),所以在这里要传入一个cls参数,而且这里的new你改造过了,所以要返回爸爸的new方法。

按造这个方法改造的单例怎么new都是同一个实例,但init仍然会被执行多次,也就是创建了几个对象就调用几次初始化方法。所以还要对init再进行一些判断。

class A:
 instance = None
 init_flag = False # 初始化标记

 def __new__(cls, *args, **kwargs):
  if cls.instance is None:
   cls.instance = super().__new__(cls)
  return cls.instance

 def __init__(self):
  if A.init_flag:
   return
  print('执行了初始化方法')
  A.init_flag = True

if __name__ == '__main__':
 a = A()
 b = A()
 print(a)
 print(b)

输出结果:

执行了初始化方法

<main.A object at 0x00000210E6F09320>

<main.A object at 0x00000210E6F09320>

总结

通过重载new方法,可以比较简单地实现单例,Python还有很多有趣的内置函数,有空可以再研究研究。

补充知识:Python饿汉式和懒汉式单例模式的实现

看代码吧~

# 饿汉式
class Singleton(object):
 # 重写创建实例的__new__方法
 def __new__(cls):
  # 如果类没有实例属性,进行实例化,否则返回实例
  if not hasattr(cls, 'instance'):
   cls.instance = super(Singleton, cls).__new__(cls)
  return cls.instance

饿汉式在创建的时候就会生成实例

# 懒汉式
class Singleton(object):
 __instance = None
 def __init__(self):
  if not self.__instance:
   print('调用__init__, 实例未创建')
  else:
   print('调用__init__,实例已经创建过了:', __instance)

 @classmethod
 def get_instance(cls):
  # 调用get_instance类方法的时候才会生成Singleton实例
  if not cls.__instance:
   cls.__instance = Singleton()
  return cls.__instance

以上这篇Python 用__new__方法实现单例的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python常用模块用法分析
Sep 08 Python
Python列表(list)常用操作方法小结
Feb 02 Python
python提取内容关键词的方法
Mar 16 Python
通过mod_python配置运行在Apache上的Django框架
Jul 22 Python
Python操作MySQL模拟银行转账
Mar 12 Python
不归路系列:Python入门之旅-一定要注意缩进!!!(推荐)
Apr 16 Python
Python 中list ,set,dict的大规模查找效率对比详解
Oct 11 Python
Django使用Celery加redis执行异步任务的实例内容
Feb 20 Python
python生成13位或16位时间戳以及反向解析时间戳的实例
Mar 03 Python
5款实用的python 工具推荐
Oct 13 Python
python 求两个向量的顺时针夹角操作
Mar 04 Python
Python深度学习之实现卷积神经网络
Jun 05 Python
python实现图像高斯金字塔的示例代码
Dec 11 #Python
Pycharm plot独立窗口显示的操作
Dec 11 #Python
Python OpenCV中的numpy与图像类型转换操作
Dec 11 #Python
使用python操作lmdb对数据读取的实例
Dec 11 #Python
PyTorch 中的傅里叶卷积实现示例
Dec 11 #Python
python中append函数用法讲解
Dec 11 #Python
python实现图像随机裁剪的示例代码
Dec 10 #Python
You might like
php中使用接口实现工厂设计模式的代码
2012/06/17 PHP
php+memcache实现的网站在线人数统计代码
2014/07/04 PHP
PHP基于回溯算法解决n皇后问题的方法示例
2017/11/07 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
2017/12/21 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
PHP PDOStatement::fetchObject讲解
2019/02/01 PHP
Avengerls vs Newbee BO3 第一场2.18
2021/03/10 DOTA
JavaScript中的property和attribute介绍
2011/12/26 Javascript
javascript将数字转换整数金额大写的方法
2015/01/27 Javascript
JavaScript原生对象之Date对象的属性和方法详解
2015/03/13 Javascript
javascript实现圣旨卷轴展开效果(代码分享)
2017/03/23 Javascript
元素全屏的设置与监听实例
2017/11/28 Javascript
vue 组件中添加样式不生效的解决方法
2018/07/06 Javascript
vue引入axios同源跨域问题
2018/09/27 Javascript
教你搭建按需加载的Vue组件库(小结)
2019/07/29 Javascript
JS求解两数之和算法详解
2020/04/28 Javascript
JavaScript中常用的3种弹出提示框(alert、confirm、prompt)
2020/11/10 Javascript
详解Python中内置的NotImplemented类型的用法
2015/03/31 Python
Python作用域用法实例详解
2016/03/15 Python
Python实现动态图解析、合成与倒放
2018/01/18 Python
Python3读取和写入excel表格数据的示例代码
2020/06/09 Python
Pycharm的Available Packages为空的解决方法
2020/09/18 Python
关于PyCharm安装后修改路径名称使其可重新打开的问题
2020/10/20 Python
Python获取android设备cpu和内存占用情况
2020/11/15 Python
python脚本定时发送邮件
2020/12/22 Python
有关HTML5 Video对象的ontimeupdate事件(Chrome上无效)的问题
2013/07/19 HTML / CSS
如何唤起类中的一个方法
2013/11/29 面试题
计算机通信工程专业毕业生推荐信
2013/12/24 职场文书
汉语言文学职业规划
2014/02/14 职场文书
纪检干部对照检查材料
2014/08/22 职场文书
中学生旷课检讨书模板
2014/10/08 职场文书
社区综治工作汇报
2014/10/27 职场文书
2014年幼儿园班级工作总结
2014/12/17 职场文书
2015年学校团委工作总结
2015/05/26 职场文书
CSS3实现的3D隧道效果
2021/04/27 HTML / CSS
Python爬虫基础初探selenium
2021/05/31 Python