• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Python中使用__new__实现单例模式并解析

python 搞代码 4年前 (2022-01-09) 21次浏览 已收录 0个评论

单例模式是一个经典设计模式,简要的说,一个类的单例模式就是它只能被实例化一次,实例变量在第一次实例化时就已经固定。

 在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 d<a style="color:transparent">本文来源gao($daima.com搞@代@#码$网</a>atetime
>>> 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__都不需要定义,在元类编程中才需要,它可以控制类的生成过程。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Python中使用__new__实现单例模式并解析

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址