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的print用法示例
Feb 11 Python
Python实现邮件的批量发送的示例代码
Jan 23 Python
Python 3.6 读取并操作文件内容的实例
Apr 23 Python
Django 多语言教程的实现(i18n)
Jul 07 Python
python 除法保留两位小数点的方法
Jul 16 Python
Python os.access()用法实例
Feb 18 Python
pycharm配置git(图文教程)
Aug 16 Python
使用python写一个自动浏览文章的脚本实例
Dec 05 Python
python3 动态模块导入与全局变量使用实例
Dec 22 Python
使用python从三个角度解决josephus问题的方法
Mar 27 Python
详解python如何引用包package
Jun 07 Python
python opencv实现图像配准与比较
Feb 09 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
Win9x/ME下Apache+PHP安装配置
2006/10/09 PHP
php解析json数据实例
2014/08/19 PHP
PHP动态柱状图实现方法
2015/03/30 PHP
php轻量级的性能分析工具xhprof的安装使用
2015/08/12 PHP
PHP实现的简单操作SQLite数据库类与用法示例
2017/06/19 PHP
jquery下动态显示jqGrid以及jqGrid的属性设置容易出现问题的解决方法
2010/10/22 Javascript
A标签中通过href和onclick传递的this对象实现思路
2013/04/19 Javascript
JS中的prototype与面向对象的实例讲解
2013/05/22 Javascript
Javascript页面添加到收藏夹的简单方法
2013/08/07 Javascript
使用indexOf等在JavaScript的数组中进行元素查找和替换
2013/09/18 Javascript
Javascript中数组sort和reverse用法分析
2014/12/30 Javascript
js实现精美的银灰色竖排折叠菜单
2015/05/16 Javascript
Javascript实现鼠标框选操作  不是点击选取
2016/04/14 Javascript
JavaScript toUpperCase()方法使用详解
2016/08/26 Javascript
jquery easyui validatebox remote的使用详解
2016/11/09 Javascript
JavaScript关联数组用法分析【概念、定义、遍历】
2017/03/15 Javascript
jQuery序列化后的表单值转换成Json
2017/06/16 jQuery
select标签设置默认选中的选项方法
2018/03/02 Javascript
Vue入门之animate过渡动画效果
2018/04/08 Javascript
Vue.js 实现微信公众号菜单编辑器功能(二)
2018/05/08 Javascript
微信小程序倒计时功能实例代码
2018/07/17 Javascript
如何通过setTimeout理解JS运行机制详解
2019/03/23 Javascript
vue 导航锚点_点击平滑滚动,导航栏对应变化详解
2020/08/10 Javascript
Python中实现对list做减法操作介绍
2015/01/09 Python
python实现可将字符转换成大写的tcp服务器实例
2015/04/29 Python
Pycharm之快速定位到某行快捷键的方法
2019/01/20 Python
使用Python自动化破解自定义字体混淆信息的方法实例
2019/02/13 Python
Python 中PyQt5 点击主窗口弹出另一个窗口的实现方法
2019/07/04 Python
Scrapy-Redis之RedisSpider与RedisCrawlSpider详解
2020/11/18 Python
面试后感谢信怎么写
2014/02/01 职场文书
产品设计开发计划书
2014/05/07 职场文书
个人思想政治总结
2015/03/05 职场文书
推荐六本经典文学奖书籍:此生必读
2019/08/22 职场文书
MySQL系列之十一 日志记录
2021/07/02 MySQL
MySQL日期时间函数知识汇总
2022/03/17 MySQL
分享MySQL常用 内核 Debug 几种常见方法
2022/03/17 MySQL