之前通过读书,了解到在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. PHP常用数组(Array)函数整理

    整理了一份PHP开发中数组操作大全,包含有数组操作的基本函数.数组的分段和填充.数组与栈.数组与列队.回调函数.排序.计算.其他的数组函数等. 一.数组操作的基本函数 数组的键名和值 array_va ...

  2. 云计算---OpenStack Neutron详解

    简介: neutron是openstack核心项目之一,提供云计算环境下的虚拟网络功能 OpenStack网络(neutron)管理OpenStack环境中所有虚拟网络基础设施(VNI),物理网络基础 ...

  3. 学习如何看懂SQL Server执行计划(一)——数据查询篇

    一.数据查询部分 1. 看到执行计划有两种方式,对sql语句按Ctrl+L,或按Ctrl+M打开显示执行计划窗口每次执行sql都会显示出相应的执行计划 2. 执行计划的图表是从右向左看的 3. SQL ...

  4. swoole 入门

    1. 概述 Swoole是PHP的一个扩展,但是它与普通的扩展不同,普通的扩展知识提供一个库函数,而Swoole扩展在运行后会接管PHP的控制器,进入时间循环.当IO时间发生后,Swoole会自动回调 ...

  5. nodejs后台集成富文本编辑器(ueditor)

    1 下载ueditor nodejs版本 2 复制public目录下面的文件 到项目静态资源public文件夹下 3 在项目根目录创建ueditor文件夹 要复制进来的内容为 4 在根目录的 uedi ...

  6. Kindeditor JS 取值问题以及上传图片后回调等

    KindEditor.ready(function (K) { var editor = K.create('#editor_id', { //上传管理 uploadJson: '/js/kinded ...

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

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

  8. asp.net mvc CodeFirst模式数据库迁移步骤

    利用Code First模式构建好基本的类后,项目也开始搭建完毕并成功运行,而且已经将数据库表结构自动生成了. 但是,我有新的类要加入,有字段需要修改,那怎么办呢,删库,跑路 ?  哈哈 利用数据库迁 ...

  9. 【学习】ie8支持rgba()透明度颜色

    (我的博客网站中的原文:http://www.xiaoxianworld.com/archives/285,欢迎遇到的小伙伴常来瞅瞅,给点评论和建议,有错误和不足,也请指出.) rgba()函数可以用 ...

  10. DOM2练习

    左右互相输入 <!DOCTYPE html><html>    <head>        <meta charset="UTF-8"&g ...