之前通过读书,了解到在Python中可以通过__new__方法来实现单例模式,代码一个示例如下,我就有了几个疑问,什么是单例模式?__new__方法是用来做什么的?用__new__方法实现的单例模式,比如下面的MyClass类,会对类的初始化有影响吗?会对类的实例方法、类方法、静态方法有影响吗?下面会说下我对这些概念的理解,如有错误,欢迎交流指出,在此表示感谢。

 class SingleTon(object):
_instance = {} def __new__(cls, *args, **kwargs):
if cls not in cls._instance:
cls._instance[cls] = super(SingleTon, cls).__new__(cls, *args, **kwargs)
print cls._instance
return cls._instance[cls] class MyClass(SingleTon):
class_val = 22

首先说下单例模式,单例模式是确保一个类只有一个实例,并且这个实例是自己创造的,在系统中用到的都是这个实例。单例模式是设计模式的一种,关于设计模式和单例模式更具体的内容,可以查看相关的书本,在后面我也要好好学习一下这些东西。

下面主要说下__new__是用来干什么的,在Python中,__new__是用来创造一个类的实例的,而__init__是用来初始化这个实例的。既然__new__用来创造实例,也就需要最后返回相应类的实例,那么如果返回的是其他类的实例,结果如何呢?见下面的代码。以下代码运行后,首先打印出NoReturn __new__然后打印出other instance,最后通过type(t)可以看到t的类型是<class '__main__.Other'>,可以知道如果__new__中不返回本类的实例的话,是没法调用__init__方法的。想要返回本类的实例,只需要把以下代码中12行的Other()改成super(NoReturn, cls).__new__(cls, *args, **kwargs)即可。

 class Other(object):
val = 123 def __init__(self):
print 'other instance' class NoReturn(object): def __new__(cls, *args, **kwargs):
print 'NoReturn __new__'
return Other() def __init__(self, a):
print a
print 'NoReturn __init__' t = NoReturn(12)
print type(t)

最后来说用__new__方法实现的单例模式,会对实例方法,类方法,静态方法,实例变量和类变量有影响吗?答案是对相应的方法是没有影响的,但是如果用不同的变量都初始化了这个实例,在后面的变量中修改实例变量和类变量的话,前面的也会相应修改,而这也正好符合单例,无论多少个变量指向了这个实例,他们指向的是同一个。在__new__中产生完实例后,每次初始化实例对象,都是产生的同一个实例,而这个实例中相关的方法、变量还是和普通的实例一样使用。测试代码以及输出如下:

 class MyClass(SingleTon):
class_val = 22 def __init__(self, val):
self.val = val def obj_fun(self):
print self.val, 'obj_fun' @staticmethod
def static_fun():
print 'staticmethod' @classmethod
def class_fun(cls):
print cls.class_val, 'classmethod' if __name__ == '__main__':
a = MyClass(1)
b = MyClass(2)
print a is b # True
print id(a), id(b) # 4367665424 4367665424
# 类型验证
print type(a) # <class '__main__.MyClass'>
print type(b) # <class '__main__.MyClass'>
# 实例方法
a.obj_fun() # 2 obj_fun
b.obj_fun() # 2 obj_fun
# 类方法
MyClass.class_fun() # 22 classmethod
a.class_fun() # 22 classmethod
b.class_fun() # 22 classmethod
# 静态方法
MyClass.static_fun() # staticmethod
a.static_fun() # staticmethod
b.static_fun() # staticmethod
# 类变量
a.class_val = 33
print MyClass.class_val #
print a.class_val #
print b.class_val #
# 实例变量
print b.val #
print a.val #

由Python通过__new__实现单例模式,所想到的__new__和__init__方法的区别的更多相关文章

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

    阅读文章前请先阅读 Python中类方法.__new__方法和__init__方法解析 单例模式是一个经典设计模式,简要的说,一个类的单例模式就是它只能被实例化一次,实例变量在第一次实例化时就已经固定 ...

  2. Python __new__ 实现单例模式 python经典面试题

    话不多说,上代码 class Singleton(object): def __new__(cls, *args, **kwargs): if not hasattr(cls, '_instance' ...

  3. python 内建函数__new__的单例模式

    今天好奇__init__和__new__的区别是什么? 我了解到: __init__:只是单纯的返回一个类对象的实例,是在__new__之后调用的 __new__:创建一个类对象实例, class S ...

  4. [python实现设计模式]-1. 单例模式

    设计模式中,最简单的一个就是 “单例模式”, 那么首先,就实现一下单例模式. 那么根据个人的理解,很快就写出第一版. # -*- coding: utf-8 -*- class Singleton(o ...

  5. python面向对象进阶 反射 单例模式 以及python实现类似java接口功能

    本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 类的成员 类的成员可以分为三大类:字段.方法和特性. 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存 ...

  6. Python学习笔记:单例模式

    单例模式:一个类无论实例化多少次,返回的都是同一个实例,例如:a1=A(), a2=A(), a3=A(),a1.a2和a3其实都是同一个对象,即print(a1 is a2)和print(a2 is ...

  7. exec , 元类,__new__, __call__ , 单例模式 , 异常

    1,类也是对象 ''' 动态语言 可以在运行期间 动态生成类 修改对象属性 静态语言 ''''' ''' type(object_or_name, bases, dict) type(object) ...

  8. python中几种单例模式的实现

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  9. python单例模式控制成只初始化一次,常规型的python单例模式在新式类和经典类中的区别。

    单例模式的写法非常多,但常规型的单例模式就是这样写的,各种代码可能略有差异,但核心就是要搞清楚类属性 实例属性,就很容易写出来,原理完全一模一样. 如下: 源码: class A(object): d ...

随机推荐

  1. (Java后端 Java web)面试时如何展示自己非技术方面的能力(其实就是综合能力)

    这篇文章的适用范围其实不仅限于Java后端或Java Web,不过其中有些是拿这方面举例的,在其它方面,大家可以举一反三,应该也能得到些启示. 我们在面试时,会发现有些候选人技术不错,比如在Java ...

  2. 编译期类型检查 in ClojureScript

    前言  话说"动态类型一时爽,代码重构火葬场",虽然有很多不同的意见(请参考),但我们看到势头强劲的TypeScript和Flow.js,也能感知到静态类型在某程度上能帮助我们写出 ...

  3. CPU 分类

    Single Core :单核CPU Dual Core   :双核CPU Quad Core  :四核CPU Hexa Core  :六核CPU Octa Core   :八核CPU 参考: htt ...

  4. 网时|ipone8爆冷,我的服务器空欢喜一场

    上周ipone可谓是占尽了风头,从face ID到全面屏,从人脸识别到逆天价格,小编都能预想到上市之后的一片火热了,苹果后台的服务器恐怕都早已做好了准备,加大带宽,稳定运行,确保万无一失. 9月22日 ...

  5. SpringMVC加载.roperties文件属性值的方法?

    1.在xml文件中引入来获取属性值就不说了. 2.在controller层获取引用配置文件中的属性值: (1).编写工具类 @Configuration @PropertySource(value=& ...

  6. SqlServer和Oracle中一些常用的sql语句3 行列转换

    --217, SQL SERVER SELECT Cust_Name , MAX(CASE WHEN Order_Date ='2009-08-01' THEN AR END) "2009- ...

  7. RabbitMQ与AMQP协议

    AMQP(Advanced Message Queuing Protocol, 高级消息队列协议)是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计 ...

  8. 安装xp遇到的问题与如何连接共享的打印机

    2013-12-5 星期四 今天下午去给曹老师鼓捣电脑去了,安装了一个xp系统,加上一些常用的办公软件,在连接上一个共享的打印机. 下面是今天我遇到的问题: 问题:安装xp系统之后,没有本地连接,只有 ...

  9. sa账户和密码丢失如何找回

    来自:http://www.cnblogs.com/xred/archive/2012/03/09/2386185.html 在网上看了很多如何修改SQLServer2005的密码的方法.大多数都是转 ...

  10. 【网络爬虫入门04】彻底掌握BeautifulSoup的CSS选择器

    [网络爬虫入门04]彻底掌握BeautifulSoup的CSS选择器 广东职业技术学院  欧浩源 2017-10-21 1.引言 目前,除了官方文档之外,市面上及网络详细介绍BeautifulSoup ...