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简单进程锁代码实例
Apr 27 Python
python+opencv轮廓检测代码解析
Jan 05 Python
微信跳一跳小游戏python脚本
Jan 05 Python
python中numpy的矩阵、多维数组的用法
Feb 05 Python
转换科学计数法的数值字符串为decimal类型的方法
Jul 16 Python
python画柱状图--不同颜色并显示数值的方法
Dec 13 Python
Pandas聚合运算和分组运算的实现示例
Oct 17 Python
Python3 hashlib密码散列算法原理详解
Mar 30 Python
Python中socket网络通信是干嘛的
May 27 Python
anaconda安装pytorch1.7.1和torchvision0.8.2的方法(亲测可用)
Feb 01 Python
Python  Asyncio模块实现的生产消费者模型的方法
Mar 01 Python
Python机器学习之基础概述
May 19 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的魔术方法__get()和__set()使用介绍
2012/09/19 PHP
zend framework配置操作数据库实例分析
2012/12/06 PHP
php计算两个文件相对路径的方法
2015/03/14 PHP
PHP实现图片自动清理的方法
2015/07/08 PHP
PHP与SQL语句常用大全
2016/12/10 PHP
使用WAMP搭建PHP本地开发环境
2017/05/10 PHP
PHP时间日期增减操作示例【date strtotime实现加一天、加一月等操作】
2018/12/21 PHP
用javascript将数据库中的TEXT类型数据动态赋值到TEXTAREA中
2007/04/20 Javascript
jquery remove方法应用详解
2012/11/22 Javascript
js字符串转成JSON
2013/11/07 Javascript
jquery 通过name快速取值示例
2014/01/24 Javascript
javascript定义变量时带var与不带var的区别分析
2015/01/12 Javascript
javascript中AJAX用法实例分析
2015/01/30 Javascript
javascript中$(function() {});写与不写有哪些区别
2015/08/10 Javascript
超实用的JavaScript代码段 附使用方法
2016/05/22 Javascript
jQuery实现的省市县三级联动菜单效果完整实例
2016/08/01 Javascript
js拖拽功能实现代码解析
2016/11/28 Javascript
bootstrap实现图片自动轮播
2016/12/21 Javascript
vue-router+vuex addRoutes实现路由动态加载及菜单动态加载
2017/09/28 Javascript
微信小程序商品详情页规格属性选择示例代码
2017/10/30 Javascript
Angular开发实践之服务端渲染
2018/03/29 Javascript
jQuery实现遍历XML节点和属性的方法示例
2018/04/29 jQuery
手把手教你 CKEDITOR 4 实现Dialog 内嵌 IFrame操作详解
2019/06/18 Javascript
jQuery--遍历操作实例小结【后代、同胞及过滤】
2020/05/22 jQuery
[50:50]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第一场 12.20
2020/12/23 DOTA
python3个性签名设计实现代码
2018/06/19 Python
OPENCV去除小连通区域,去除孔洞的实例讲解
2018/06/21 Python
利用django+wechat-python-sdk 创建微信服务器接入的方法
2019/02/20 Python
安装python3.7编译器后如何正确安装opnecv的方法详解
2020/06/16 Python
护士的岗位职责
2013/12/04 职场文书
会计专业应届生自荐信
2014/02/07 职场文书
2014政务公开实施方案
2014/02/19 职场文书
电视购物广告词
2014/03/19 职场文书
政治学专业毕业生求职信
2014/08/11 职场文书
担保书格式范文
2015/09/22 职场文书
「约定的梦幻岛」作画发布诺曼生日新绘
2022/03/21 日漫