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

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

在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__实现单例模式并解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • 常见的在Python中实现单例模式的三种方法

    单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案. 单例模式的要点有三个:一是某个类只能有一个实例:二是它必须自行创建这个实例:三是它必须自行向整个系统提供这个实例.在Python中,单例模式有以下几种实现方式. 方法一.实现__new__方法,然后将类的一个实例绑定到类变量_instanc

  • 详解python单例模式与metaclass

    单例模式的实现方式 将类实例绑定到类变量上 class Singleton(object): _instance = None def __new__(cls, *args): if not isinstance(cls._instance, cls): cls._instance = super(Singleton, cls).__new__(cls, *args) return cls._instance 但是子类在继承后可以重写__new__以失去单例特性 class D(Singleto

  • 5种Python单例模式的实现方式

    本文为大家分享了Python创建单例模式的5种常用方法,供大家参考,具体内容如下 所谓单例,是指一个类的实例从始至终只能被创建一次. 方法1: 如果想使得某个类从始至终最多只有一个实例,使用__new__方法会很简单.Python中类是通过__new__来创建实例的: class Singleton(object): def __new__(cls,*args,**kwargs): if not hasattr(cls,'_inst'): cls._inst=super(Singleton,cl

  • Python单例模式的两种实现方法

    Python单例模式的两种实现方法 方法一  import threading class Singleton(object): __instance = None __lock = threading.Lock() # used to synchronize code def __init__(self): "disable the __init__ method" @staticmethod def getInstance(): if not Singleton.__instanc

  • Python单例模式实例分析

    本文实例讲述了Python单例模式的使用方法.分享给大家供大家参考.具体如下: 方法一 复制代码 代码如下: import threading    class Singleton(object):      __instance = None        __lock = threading.Lock()   # used to synchronize code        def __init__(self):          "disable the __init__ method&

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

    单例模式是一个经典设计模式,简要的说,一个类的单例模式就是它只能被实例化一次,实例变量在第一次实例化时就已经固定. 在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

  • python中使用%与.format格式化文本方法解析

    初学python,看来零零碎碎的格式化文本的方法,总结一下python中格式化文本的方法.使用不当的地欢迎指出谢谢. 1.首先看使用%格式化文本 常见的占位符: 常见的占位符有: %d 整数 %f 浮点数 %s 字符串 %x 十六进制整数 使用方法: >>> 'Hello, %s' % 'world' 'Hello, world' >>> 'Hi, %s, you have $%d.' % ('Michael', 1000000) 'Hi, Michael, you h

  • python中set()函数简介及实例解析

    set函数也是python内置函数的其中一个,属于比较基础的函数.其具体介绍和使用方法,下面进行介绍. set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集.差集.并集等. set,接收一个list作为参数 list1=[1,2,3,4] s=set(list1) print(s) #逐个遍历 for i in s: print(i) 输出: set([1, 2, 3, 4]) 1 2 3 4 使用add(key)往集合中添加元素,重复的元素自动过滤 list1

  • python中删除某个元素的方法解析

    这篇文章主要介绍了python中删除某个元素的方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python中关于删除list中的某个元素,一般有三种方法:remove.pop.del 1.remove: 删除单个元素,删除首个符合条件的元素,按值删除 举例说明: >>> str=[1,2,3,4,5,2,6] >>> str.remove(2) >>> str [1, 3, 4, 5, 2,

  • 深入理解Python中的 __new__ 和 __init__及区别介绍

    本文的目的是讨论Python中 __new__ 和 __ini___ 的用法. __new__ 和 __init__ 的区别主要表现在:1. 它自身的区别:2. 及在Python中新式类和老式类的定义. 理解 __new__ 和 __init__ 的区别 这两个方法的主要区别在于:__new__ 负责对象的创建而 __init__ 负责对象的初始化.在对象的实例化过程中,这两个方法会有些细微的差别,表现于:如何工作,何时定义. Python中两种类的定义方式 Python 2.x 中类的定义分为

  • Python中的引用和拷贝实例解析

    这篇文章主要介绍了python中的引用和拷贝实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.引用 a = ['a', 'b', 'c'] b = a print(id(a)) print(id(b)) 135300560 135300560 可以看到,变量a 和 b 的 id是完全一样的,这就说明a和b是同时指向内存的同一个区域的,即b随a的变化而变化. a = ['a', 'b', 'c'] b = a a[1] = 'd' pr

  • Python中使用gflags实例及原理解析

    这篇文章主要介绍了Python中使用gflags实例及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 安装命令pip install python-gflags 使用示例: import gflags FLAGS = gflags.FLAGS gflags.DEFINE_string('name', 'ming', 'this is a value') gflags.DEFINE_integer('qps', 0, 'test qps'

  • Python中json.dumps()函数的使用解析

    json.dumps将一个Python数据结构转换为JSON import json data = { 'name' : 'myname', 'age' : 100, } json_str = json.dumps(data) json库的一些用法 方法 作用 json.dumps() 将python对象编码成Json字符串 json.loads() 将Json字符串解码成python对象 json.dump() 将python中的对象转化成json储存到文件中 json.load() 将文件中

  • 实例解析Python中的__new__特殊方法

    __new__ 方法是什么? 如果将类比喻为工厂,那么__init__()方法则是该工厂的生产工人,__init__()方法接受的初始化参 数则是生产所需原料,__init__()方法会按照方法中的语句负责将原料加工成实例以供工厂出货.而 __new__()则是生产部经理,__new__()方法可以决定是否将原料提供给该生产部工人,同时它还决定着出 货产品是否为该生产部的产品,因为这名经理可以借该工厂的名义向客户出售完全不是该工厂的产品. __new__()方法的特性: 1.__new__()方

  • 详解Python中的__new__、__init__、__call__三个特殊方法

    __new__: 对象的创建,是一个静态方法,第一个参数是cls.(想想也是,不可能是self,对象还没创建,哪来的self) __init__ : 对象的初始化, 是一个实例方法,第一个参数是self. __call__ : 对象可call,注意不是类,是对象. 先有创建,才有初始化.即先__new__,而后__init__. 上面说的不好理解,看例子. 1.对于__new__ class Bar(object): pass class Foo(object): def __new__(cls

随机推荐