由Python通过__new__实现单例模式,所想到的__new__和__init__方法的区别
之前通过读书,了解到在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__方法的区别的更多相关文章
- Python中使用__new__实现单例模式并解析
阅读文章前请先阅读 Python中类方法.__new__方法和__init__方法解析 单例模式是一个经典设计模式,简要的说,一个类的单例模式就是它只能被实例化一次,实例变量在第一次实例化时就已经固定 ...
- Python __new__ 实现单例模式 python经典面试题
话不多说,上代码 class Singleton(object): def __new__(cls, *args, **kwargs): if not hasattr(cls, '_instance' ...
- python 内建函数__new__的单例模式
今天好奇__init__和__new__的区别是什么? 我了解到: __init__:只是单纯的返回一个类对象的实例,是在__new__之后调用的 __new__:创建一个类对象实例, class S ...
- [python实现设计模式]-1. 单例模式
设计模式中,最简单的一个就是 “单例模式”, 那么首先,就实现一下单例模式. 那么根据个人的理解,很快就写出第一版. # -*- coding: utf-8 -*- class Singleton(o ...
- python面向对象进阶 反射 单例模式 以及python实现类似java接口功能
本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 类的成员 类的成员可以分为三大类:字段.方法和特性. 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存 ...
- Python学习笔记:单例模式
单例模式:一个类无论实例化多少次,返回的都是同一个实例,例如:a1=A(), a2=A(), a3=A(),a1.a2和a3其实都是同一个对象,即print(a1 is a2)和print(a2 is ...
- exec , 元类,__new__, __call__ , 单例模式 , 异常
1,类也是对象 ''' 动态语言 可以在运行期间 动态生成类 修改对象属性 静态语言 ''''' ''' type(object_or_name, bases, dict) type(object) ...
- python中几种单例模式的实现
单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...
- python单例模式控制成只初始化一次,常规型的python单例模式在新式类和经典类中的区别。
单例模式的写法非常多,但常规型的单例模式就是这样写的,各种代码可能略有差异,但核心就是要搞清楚类属性 实例属性,就很容易写出来,原理完全一模一样. 如下: 源码: class A(object): d ...
随机推荐
- Angular JS中的路由
前 言 本章节将为大家介绍 AngularJS 路由.AngularJS 路由允许我们通过不同的 URL 访问不同的内容.通过 AngularJS 可以实现多视图的单页We ...
- Linux下搭建tomcat和jre的环境
1.下载linux版本的tomcat和jre tomcat下载:http://pan.baidu.com/s/1nt7D87J: jre下载:http://pan.baidu.com/s/1sj4hA ...
- 使用svn控制系统的优缺点和注意事项
1.当无法连接到中央版本库的环境下,你无法提交代码,将代码加入版本控制.公司一般是局域网,所以使用环境问题不大. 2.svn的备份要备份所有代码数据以及所有更改的版本记录. 3.svn服务端运行方式: ...
- zoj3953 Intervals 最大不重叠区间加强版 zoj排名第一~
Intervals Time Limit: 1 Second Memory Limit:65536 KB Special Judge Chiaki has n intervals ...
- asp.net或者MVC定时自动执行某操作
using System; using System.IO; using System.Runtime.CompilerServices; using System.Text; namespace S ...
- c#使用GDI+简单绘图
private void button2_Click(object sender, EventArgs e) { Bitmap image = new Bitmap(200, 200); Graphi ...
- JavaScript实现常见算法面试题
算法题目部分参照了<进军硅谷>这本书. github:https://github.com/qcer/Algo-Practice (如果你觉得有帮助,记得给个star,THS) 一.排序 ...
- jquery系列教程6-ajax的应用全解
点击打开: jquery系列教程1-选择器全解 jquery系列教程2-style样式操作全解 jquery系列教程3-DOM操作全解 jquery系列教程4-事件操作全解 jquery系列教程5-动 ...
- 【学习】苹果iPhone safari浏览器样式重置修复按钮圆角bug
iPhone safari浏览器中,input按钮会按苹果的默认UI来渲染,例如,写的按钮明明是这个样的: 但是实际就会是这个样子: 怎么办呢? 为按钮添加:-webkit-appearance: n ...
- 开始Java8之旅(四) --四大函数接口
前言 Java8中函数接口有很多,大概有几十个吧,具体究竟是多少我也数不清,所以一开始看的时候感觉一脸懵逼,不过其实根本没那么复杂,毕竟不应该也没必要把一个东西设计的很复杂. 几个单词 在学习 ...