Python 用__new__方法实现单例的操作
作者:hiudawn 发布时间:2023-05-22 08:22:41
标签:Python,new,单例
介绍
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
来源:https://blog.csdn.net/hiudawn/article/details/80377510


猜你喜欢
- 关于axios的封装下面代码参考了 vue-element-admin 中的封装方式,request.js 文件如下,封装一个 axios
- 函数原型与参数详解OpenCV提供了cv.Canny()方法,该方法将输入的原始图像转换为边缘图像。该方法的原型为:cv.Canny(ima
- 1.表达式操作符Table 1 算术操作符操作符 语法 含义+ a + b 相加 - a - b 相减 - - a
- 1.交换变量x = 6y = 5x, y = y, xprint x>>> 5print y>>> 62
- 本文记录了mysql安装详细教程,分享给大家。一、版本的选择之前安装的Mysql,现在才来总结,好像有点晚,后台换系统了,现在从新装上Mys
- 如果你从未为MySQL设置根用户密码,服务器在以根用户身份进行连接时不需要密码。但是,建议你为每个账户设置密码。如果你以前设置了根用户密码,
- 1.什么是接口接口就是一种规范与标准,在生活中经常见接口,例如:笔记本电脑的USB接口,可以将任何厂商生产的鼠标与键盘,与电脑进行链接。为什
- 使用 vue-cli构建的项目,在 默认情况下 ,执行 npm run build 会将所有的js代码打包为一个整体,打包位置是
- 本文总结了input的各种使用方法,挺全面的1.取消按钮按下时的虚线框在input里添加属性值 hideFocus 或者 HideFocus
- 这篇文章主要介绍了简单了解Python3 bytes和str类型的区别和联系,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的
- 新建图像文件后选Channels面板,新建Alpha1通道:输入文字; &nbs
- 一、使用我使用的是python3,可以自行搜索下载二、安装phone模块pip install phone三、测试代码如下:from pho
- mysql的case when字段为空,nullname字段为null时替换为 ‘该字段为空’SEL
- 本文实例讲述了Python简单网络编程。分享给大家供大家参考,具体如下:内容目录1. 客户端(client.py)2. 服务端(server
- ASP由于是一种古老的语言,它的一些功能对UTF-8支持非常差。比如,你想生成一个UTF-8格式的文件,使用常用的 scrīpting.Fi
- 项目:基于Pymysql的专家随机抽取系统引入库函数:>>> import treelib>>> fro
- 很开心可以和导师阿坚在08gui大赛中一起去完成《fight》的图标设计,在这个过程中真的是受益匪浅!这里我谈一下在这个过程的一些小小心得。
- 代码: import os while True: dynamic = input('输入计算表达式:') if dynam
- 在SQL Server数据库操作中,对数据库复制时出现了以下的错误,错误信息如下图所示:SQL Server数据库复制失败的原因及解决方案出
- 今天项目上遇到一个问题,需要在点击a标签时,将完整的内容显示出来原先是想用jquery的click方法<a ownattr=“……”