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缩进区别分析
Feb 15 Python
如何在Python函数执行前后增加额外的行为
Oct 20 Python
python下如何查询CS反恐精英的服务器信息
Jan 17 Python
速记Python布尔值
Nov 09 Python
解决Python网页爬虫之中文乱码问题
May 11 Python
如何用python整理附件
May 13 Python
浅谈DataFrame和SparkSql取值误区
Jun 09 Python
python多线程并发及测试框架案例
Oct 15 Python
python实现一次性封装多条sql语句(begin end)
Jun 06 Python
详解Pandas 处理缺失值指令大全
Jul 30 Python
Python利用socket模块开发简单的端口扫描工具的实现
Jan 27 Python
python Protobuf定义消息类型知识点讲解
Mar 02 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 会话(session 时间设定)使用入门代码
2008/06/05 PHP
php 需要掌握的东西 不做浮躁的人
2009/12/28 PHP
php自动加载的两种实现方法
2010/06/21 PHP
PHP容易忘记的知识点分享
2013/04/30 PHP
采用header定义为文件然后readfile下载(隐藏下载地址)
2014/01/31 PHP
PHP判断表单复选框选中状态完整例子
2014/06/24 PHP
PHP file_get_contents函数读取远程数据超时的解决方法
2015/05/13 PHP
基于PHP实现通过照片获取ip地址
2016/04/26 PHP
完美解决phpdoc导出文档中@package的warning及Error的错误
2016/05/17 PHP
Thinkphp3.2.3分页使用实例解析
2016/07/28 PHP
php利用fsockopen GET/POST提交表单及上传文件
2017/05/22 PHP
thinkPHP框架实现的简单计算器示例
2018/12/07 PHP
jquery对dom的操作常用方法整理
2013/06/25 Javascript
jquery cookie实现的简单换肤功能适合小网站
2013/08/25 Javascript
replace()方法查找字符使用示例
2013/10/28 Javascript
利用JavaScript实现新闻滚动效果(实例代码)
2013/11/27 Javascript
JavaScript基础篇(3)之Object、Function等引用类型
2015/11/30 Javascript
jQuery实现返回顶部功能
2016/02/23 Javascript
基于javascript实现按圆形排列DIV元素(三)
2016/12/02 Javascript
jquery实现文本框的禁用和启用
2016/12/07 Javascript
深入理解选择框脚本[推荐]
2016/12/13 Javascript
bootstrap-table实现服务器分页的示例 (spring 后台)
2017/09/01 Javascript
微信小程序调用摄像头隐藏式拍照功能
2018/08/22 Javascript
[07:40]DOTA2每周TOP10 精彩击杀集锦vol.4
2014/06/25 DOTA
python进阶教程之循环相关函数range、enumerate、zip
2014/08/30 Python
Linux CentOS7下安装python3 的方法
2018/01/21 Python
pycharm重置设置,恢复默认设置的方法
2018/10/22 Python
Windows 下更改 jupyterlab 默认启动位置的教程详解
2020/05/18 Python
Python使用jupyter notebook查看ipynb文件过程解析
2020/06/02 Python
关于HTML5的22个初级技巧(图文教程)
2012/06/21 HTML / CSS
JD Sports意大利:英国篮球和运动时尚的领导者
2017/10/29 全球购物
Champion澳大利亚官网:美国冠军运动服装
2018/05/07 全球购物
公司面试感谢信
2014/02/01 职场文书
《称赞》教学反思
2016/02/17 职场文书
Python3 多线程(连接池)操作MySQL插入数据
2021/06/09 Python
Android开发之底部导航栏的快速实现
2022/04/28 Java/Android