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

标签:Python,new,单例模式
0
投稿

猜你喜欢

  • SQLserver查询数据类型为ntext是空或NULL值的方法

    2024-01-24 18:40:52
  • PHP延迟静态绑定示例分享

    2024-06-05 15:42:24
  • Python3计算三角形的面积代码

    2022-06-20 21:03:54
  • flash(swf)遮住网页内容div的解决

    2007-10-31 07:29:00
  • SQLServer中的切割字符串SplitString函数

    2011-12-01 08:14:09
  • SQL Server 使用join all优化 or 查询速度

    2024-01-26 09:11:37
  • Python基础之常用库常用方法整理

    2022-10-30 10:43:26
  • python工具dtreeviz决策树可视化和模型可解释性

    2023-01-12 03:46:55
  • c++与python实现二分查找的原理及实现

    2021-11-23 21:09:06
  • MySQL 数据库 like 语句通配符模糊查询小结

    2024-01-20 03:41:30
  • PHP IN_ARRAY 函数使用注意事项

    2023-11-16 19:24:24
  • 解决python调用matlab时的一些常见问题

    2022-10-13 16:11:01
  • 详解Python的迭代器、生成器以及相关的itertools包

    2022-07-24 01:03:44
  • MySQL中由load data语句引起死锁的解决案例

    2024-01-19 19:37:14
  • 详解Python中的各种函数的使用

    2022-03-23 22:09:52
  • pytorch torchvision.ImageFolder的用法介绍

    2023-05-29 17:20:49
  • PHP高级编程实例:编写守护进程

    2023-10-27 02:03:22
  • python如何实现质数求和

    2023-03-02 20:17:24
  • Pycharm 设置默认解释器路径和编码格式的操作

    2021-10-26 19:19:54
  • 一篇文章告诉你如何用python进行自动化测试,调用c程序

    2021-10-08 09:14:49
  • asp之家 网络编程 m.aspxhome.com