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调用shell的方法
Nov 20 Python
Python中使用logging模块打印log日志详解
Apr 05 Python
Python的动态重新封装的教程
Apr 11 Python
Python使用matplotlib填充图形指定区域代码示例
Jan 16 Python
python微信跳一跳游戏辅助代码解析
Jan 29 Python
python中的for循环
Sep 28 Python
Python实现的读取文件内容并写入其他文件操作示例
Apr 09 Python
windows系统中Python多版本与jupyter notebook使用虚拟环境的过程
May 15 Python
python对XML文件的操作实现代码
Mar 27 Python
python进度条显示之tqmd模块
Aug 22 Python
详解Python流程控制语句
Oct 28 Python
python 解决函数返回return的问题
Dec 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
joomla jce editor 解决上传中文名文件失败问题
2013/06/09 PHP
学习php设计模式 php实现装饰器模式(decorator)
2015/12/07 PHP
PHP基于SPL实现的迭代器模式示例
2018/04/22 PHP
关于IE浏览器以及Firefox下的javascript冒泡事件的响应层级
2010/10/14 Javascript
点击隐藏页面左栏或右栏实现js代码
2013/04/01 Javascript
图片上传判断及预览脚本的效果实例
2013/08/07 Javascript
js window.print实现打印特定控件或内容
2013/09/16 Javascript
自己写的Javascript计算时间差函数
2013/10/28 Javascript
JavaScript判断数组是否包含指定元素的方法
2015/07/01 Javascript
vue2.X组件学习心得(新手必看篇)
2017/07/05 Javascript
vue中当图片地址无效的时候,显示默认图片的方法
2018/09/18 Javascript
基于elementUI使用v-model实现经纬度输入的vue组件
2019/05/12 Javascript
少女风vue组件库的制作全过程
2019/05/15 Javascript
[03:04]DOTA2英雄基础教程 影魔
2013/12/11 DOTA
[52:27]2018DOTA2亚洲邀请赛 3.31 小组赛B组 paiN vs Secret
2018/04/01 DOTA
Python查找函数f(x)=0根的解决方法
2015/05/07 Python
Python正则表达式常用函数总结
2017/06/24 Python
JPype实现在python中调用JAVA的实例
2017/07/19 Python
Python 中 Virtualenv 和 pip 的简单用法详解
2017/08/18 Python
python+matplotlib实现礼盒柱状图实例代码
2018/01/16 Python
使用Python的Django和layim实现即时通讯的方法
2018/05/25 Python
Python图像处理之图片文字识别功能(OCR)
2019/07/30 Python
kafka监控获取指定topic的消息总量示例
2019/12/23 Python
Python 实现一个简单的web服务器
2021/01/03 Python
基于zepto的插件之移动端无缝向上滚动并上下触摸滑动实例代码
2016/12/20 HTML / CSS
Merrell迈乐澳大利亚网站:购买户外登山鞋
2017/05/28 全球购物
关于.NET, HTML的五个问题
2012/08/29 面试题
爱护公共设施演讲稿
2014/09/13 职场文书
小学音乐教师个人工作总结
2015/02/05 职场文书
大学生预备党员自我评价
2015/03/04 职场文书
呐喊读书笔记
2015/06/30 职场文书
《只有一个地球》教学反思
2016/02/16 职场文书
Pytest之测试命名规则的使用
2021/04/16 Python
基于Python实现的购物商城管理系统
2021/04/27 Python
CSS布局之浮动(float)和定位(position)属性的区别
2021/09/25 HTML / CSS
Python实现视频自动打码的示例代码
2022/04/08 Python