Python中使用__new__实现单例模式并解析
作者:Pykk2019 发布时间:2021-10-29 23:11:22
单例模式是一个经典设计模式,简要的说,一个类的单例模式就是它只能被实例化一次,实例变量在第一次实例化时就已经固定。
在Python中常见的单例模式有None,这就是一个很典型的设计,通常使用 if xxx is None或者if xxx is not None来比较运算。
Python实现单例模式
代码如下:
class MyClass:
_instance = None
_first_init = False
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, var1, var2):
cls = type(self)
if not cls._first_init:
self.var1 = var1
self.var2 = var2
cls._first_init = True
如上所示,我创建了一个MyClass的类,定义了两个类变量,第一个是_instance,它负责保存该类创建的实例。第二个是_first_init,它是一个布尔值,保存是否为第一次实例化该类。
在__new__方法中(构造函数),判断是否存在_instance这个类变量,如果之前已经实例化了,直接返回。如果是第一次实例化,就会为_instance类变量绑定实例,使用super().__new__(cls)创建实例,即调用父类object.__new__(MyClass)创建实例。
在__init__方法中(初始化函数),我们通过cls=type(self)获取MyClass类,判断是否第一次实例化。如果是第一次实例化,就绑定实例变量。否则什么都不做.
运行效果
我们创建两个实例,来对比
>>> instance1 = MyClass(1, 2)
>>> instance2 = MyClass(7, 5)
>>> id(instance1) == id(instance2)
True
>>> instance2.var1
1
可以看到,这两个实例的内存地址都相同,而且第一次实例化后变量已经固定了,全局不会再改变。
这就是单例模式的实现。
ps:下面看下Python中类方法、__new__方法和__init__方法解析
在编程语言中创建一个类,有构造方法这样的一个术语。而在Python中,通常大家都认为__init__是构造方法,其实并不完全等同。在构建类中,有一个特殊的方法__new__,这个才能等同为构造方法。
__new__是一个类方法,我们在定义一个类方法时需要在函数前打上@classmethod装饰器,而__new__不需要,因为它经过特殊处理。为了理解__new__方法,我们先来看看类方法是什么。
类方法
class MyClass:
@classmethod
def test(cls):
print(cls.__name__)
MyClass.test()
#输出 MyClass
在MyClass类中,test方法就是类方法,它传入第一个参数为cls,其实就是MyClass类,打印cls.__name__可以看到结果。类方法可以直接 类名.方法名()调用。通常类方法是备选构造方法。
类方法的应用
>>> from datetime import datetime
>>> datetime.fromtimestamp(324234)
datetime.datetime(1970, 1, 5, 2, 3, 54)
如上所示,内置的datetime包中的fromtimestamp就是类方法,可以从多种方式构造出datetime对象。
__new__方法
def __new__(cls, a):
return super().__new__(cls)
__new__是类方法,所以第一个参数也是cls,剩下的参数就是构造方法里需要的参数了。通常__new__都不需要定义,在元类编程中才需要,它可以控制类的生成过程。
__new__必须返回一个实例(instance),传入到__init__方法中的self参数,也就是实例变量。这里返回父类(object)的__new__方法用来创建一个新的实例。相当于
obj = object.__new__(MyClass)
obj = MyClass()
#obj是实例,上面两个方式等同
其中,MyClass是类,obj是实例(instance)
__init__方法
__new__是构造方法,那么__init__就是初始化函数,它负责将变量绑定到实例中,更新实例的__dict__字典。其中第一个参数self就是__new__的返回值,是类的实例。__new__方法先于__init__方法执行
def __init__(self, a):
self.a = a
结合使用
class MyClass:
def __new__(cls, a):
return super().__new__(cls)
def __init__(self, a):
self.a = a
obj = MyClass(3)
print(obj.a)
要点
1.__new__是构造方法,__init__是初始化函数。
2.__new__通常不需要手动定义,一般在元类编程中使用,控制类的生成过程。
3.__new__第一个被执行,然后执行__init__绑定实例变量。
4.__new__必须有返回值,返回值是该类的实例,它会被__init__函数接收,通常叫做self变量
总结
以上所述是小编给大家介绍的Python中使用__new__实现单例模式并解析,网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
来源:https://www.cnblogs.com/PyKK2019/p/11081883.html


猜你喜欢
- 一、什么要备份数据库 ?在现实IT世界里,我们使用的服务器硬件可能因为使用时间过长,而发生故障;Windows系列服务器有可能蓝屏或者感染病
- 导言:本文一步一步手把手教你打造一个极酷的三层分离的标准滑动门导航菜单,从思路、原理、步骤,手段可谓“无所不用其极”,即便你是菜鸟,相信你看
- 层叠样式表(css)是Web设计的一种语言,CSS的下一代版本CSS3已经蓄势待发。你是否可望开始使用它们却又不知从何下手呢?虽然还有一些新
- python的图形用户界面我是大帅哥啊 python的图形用户界面msgbox的使用ccbox的使用buttonbox的使用buttonbo
- 马上要过年了,用 Python 写一副春联&福字送给大家,本文我们主要用到的 Python 库为 tkinter,下面一起来看一下具
- Observer模式也叫观察者模式,是由GoF提出的23种软件设计模式的一种。Observer模式是行为模式之一,它的作用是当一个对象的状态
- 内置函数Built-in Functionsabs()dict()help()min()setattr()all()dir()hex()ne
- 一、Less/Scss变量换肤具体实现:1、初始化vue项目2、安装插件:npm install style-resources-loade
- 众所周知,我们可以通过索引值(或称下标)来查找序列类型(如字符串、列表、元组...)中的单个元素,那么,如果要获取一个索引区间的元素该怎么办
- 有时我们在定义字段名及别名时所用名与oracle关键字同名,这时该如何处理呢? 其实很简单,只要在此关键字加上"",如&
- 1.安装wkhtmltopdf下载地址:https://wkhtmltopdf.org/downloads.html我测试用的是window
- 本文实例为大家分享了python实现画圆功能的具体代码,供大家参考,具体内容如下import numpy as np import matp
- 当然有其它工具可以做这件事,但如果客户不允许你在服务器乱装东西时这个脚本就会有用了。 DECLARE @tbImportTables tab
- 大家都知道连续的英文或数字能是容器被撑大,不能根据容器的大小自动换行,网页设计初学者可能不知道怎么处理,下面是CSS如何将他们换行的方法!对
- 有些时候我们发现一些模块没有提供pip install 命令和安装教程 , 只提供了一个setup.py文件 , 这个时候如何安装呢?步骤打
- 前几篇都是手动录入或随机函数产生的数据。实际有许多类型的文件,以及许多方法,用它们从文件中提取数据来图形化。比如之前python基础(12)
- 概 述 ---- 现在有不少介绍利用ASP实现动态分页的文章,方法大同小异,就是每次利用ADO返回原始
- 前言在AI领域,来快速实现一个idea:前后端开发+部署+展现,如果走传统的前后端分离开发+服务器docker部署等方式,会很重且入门成本很
- PyQt5动态(可拖动控件大小)布局控件QSplitter简介PyQt还提供了特殊的布局管理器QSplitter。它可以动态地拖动子控件之间
- python运行其他程序的实现方法