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(一)Python环境安装
Aug 20 Python
Python使用CMD模块更优雅的运行脚本
May 11 Python
详解Django框架中用户的登录和退出的实现
Jul 23 Python
Python入门必须知道的11个知识点
Mar 21 Python
如何用Python合并lmdb文件
Jul 02 Python
django框架自定义用户表操作示例
Aug 07 Python
python 解压pkl文件的方法
Oct 25 Python
Python 3.3实现计算两个日期间隔秒数/天数的方法示例
Jan 07 Python
pyqt弹出新对话框,以及关闭对话框获取数据的实例
Jun 18 Python
Python对接支付宝支付自实现功能
Oct 10 Python
python ftplib模块使用代码实例
Dec 31 Python
pycharm 复制代码出现空格的解决方式
Jan 15 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 pathinfo()获得文件的路径、名称等信息说明
2011/09/13 PHP
程序员的表白神器“520”大声喊出来
2016/05/20 PHP
php面向对象之反射功能与用法分析
2017/03/29 PHP
PHP设计模式之 策略模式Strategy详解【对象行为型】
2020/05/01 PHP
jQuery对象和DOM对象的相互转化实现代码
2010/03/02 Javascript
javascript 操作select下拉列表框的一点小经验
2010/03/20 Javascript
jQuery旋转插件—rotate支持(ie/Firefox/SafariOpera/Chrome)
2013/01/16 Javascript
JavaScript全排列的六种算法 具体实现
2013/06/29 Javascript
jquery、js调用iframe父窗口与子窗口元素的方法整理
2014/07/31 Javascript
JavaScript动态修改网页元素内容的方法
2015/03/21 Javascript
详解Bootstrap glyphicons字体图标
2016/01/04 Javascript
关于function类中定义变量this的简单说明
2016/05/28 Javascript
Bootstrap开发实战之响应式轮播图
2016/06/02 Javascript
jQuery中的select操作详解
2016/11/29 Javascript
JS实现瀑布流布局
2017/10/21 Javascript
JS匿名函数和匿名自执行函数概念与用法分析
2018/03/16 Javascript
react native 原生模块桥接的简单说明小结
2019/02/26 Javascript
vue本地打开build后生成的dist文件夹index.html问题
2019/09/04 Javascript
[34:39]DOTA2上海特级锦标赛主赛事日 - 4 败者组第四轮#1COL VS EG第二局
2016/03/05 DOTA
python类参数self使用示例
2014/02/17 Python
详解Python的Django框架中manage命令的使用与扩展
2016/04/11 Python
Python multiprocess pool模块报错pickling error问题解决方法分析
2019/03/20 Python
使用Python刷淘宝喵币(低阶入门版)
2019/10/30 Python
Python正则表达式如何匹配中文
2020/05/27 Python
Python爬虫如何破解JS加密的Cookie
2020/11/19 Python
鼠标滚轮事件和Mac触控板双指事件
2019/12/23 HTML / CSS
新西兰第一的行李箱网站:luggage.co.nz
2019/07/22 全球购物
Ruby如何进行文件操作
2014/07/17 面试题
蛋糕店创业计划书范文
2014/09/21 职场文书
普通党员四风问题对照检查材料
2014/09/27 职场文书
2014最新股权信托合同协议书
2014/11/18 职场文书
求职自荐信怎么写
2015/03/04 职场文书
远程教育集中轮训基层干部培训班学习心得体会
2016/01/09 职场文书
如何书写公司员工保密协议?
2019/06/27 职场文书
JavaWeb 入门篇:创建Web项目,Idea配置tomcat
2021/07/16 Java/Android
muduo TcpServer模块源码分析
2022/04/26 Redis