python单例模式控制成只初始化一次,常规型的python单例模式在新式类和经典类中的区别。
单例模式的写法非常多,但常规型的单例模式就是这样写的,各种代码可能略有差异,但核心就是要搞清楚类属性 实例属性,就很容易写出来,原理完全一模一样。
如下:
源码:
- class A(object):
- def __new__(cls, *args, **kwargs):
- if not hasattr(cls, '__inst'):
- print('执行new')
- obj = super(A, cls).__new__(cls)
- setattr(cls, '__inst', obj)
- return obj
- else:
- return cls.__dict__['__inst']
- def __init__(self, x):
- print('执行init')
- self.x = x
- if __name__ == '__main__':
- a1 = A(1)
- print('a1.x ', a1.x)
- a2 = A(2)
- print('a2.x ', a2.x)
- print('a1.x ', a1.x)
- a3 = A.__new__(A)
- # a3.__init__(3) # a3 = A(3) 实际是调用了new和init方法,此处屏蔽调用init
- print('a3.x ', a3.x)
- print(id(a1), id(a2), id(a3))
实例化了三个对象,执行结果可以猜猜:
可以发现,执行了一次new,但执行了两次init,这是在新式类下运行的,python3默认是新式类,不管有没有继承object。
如果是python2,且不继承object,实际上是只会打印执行一次init。所以这是py2和py3的又一个区别,经典类和新式类区别非常多,新式类的反射方法也与经典类有些不同。但一般文章只说新式类和经典类的区别只是广度优先和深度优先,误导。
3、终极目标就是使python3的实例也不多执行力一次init,(因为虽然单例模式能控制成是所有类的实例指向同一个对象,但有时候的单例模式初始化是建立一个io连接或者资源池,这样每次执行初始化浪费一些时间)
三种方法,一种是增加一个类属性做标志,在init方法中增加if判断
第二种是,不使用 a = A(xxxx),而使用a = A.__new__(A),因为a = A(xxxx),实际上是a = A.__new__(A),和a.__init__(xxx)
第三种是自己写一个名字例如叫 _custom_init的方法,不写__init__方法,在new中生成self(就是实例),new里面显式手动调用此方法,这样也可以避免自动执行__init__
4、还有一种方式是使用装饰器,如果按照这个写法也不会执行多次init
单例模式装饰器
- #coding=utf8
- from functools import wraps
- def singleton(cls):
- print cls
- instances = {}
- @wraps(cls)
- def getinstance(*args, **kw):
- if cls not in instances:
- instances[cls] = cls(*args, **kw)
- return instances[cls]
- return getinstance
- @singleton
- class MyClass(object):
- a = 1
- m1=MyClass()
- m2=MyClass()
- print m1 is m2
或者元类单例模式,
单例模式元类
5、在实际项目中我用的单例模式有一些,不是很多,享元模式就可以了,享元模式是对一个重点属性在不同对象中保证该属性是指向同一个对象,使用更为灵活,这个重点属性通常是一个io连接或资源池,或者计算代价十分大的东西,以免造成实例化浪费巨大的时间。
python单例模式控制成只初始化一次,常规型的python单例模式在新式类和经典类中的区别。的更多相关文章
- python之继承、抽象类、新式类和经典类
一.上节补充1.静态属性静态属性 : 类的属性,所有的对象共享这个变量 如果用对象名去修改类的静态属性:在对象的空间中又创建了一个属性,而不能修改类中属性的值 操作静态属性应该用类名来操作 例1:请你 ...
- python中新式类和经典类
python中的类分为新式类和经典类,具体有什么区别呢?简单的说, 1.新式类都从object继承,经典类不需要. Python 2.x中默认都是经典类,只有显式继承了object才是新式类 Pyth ...
- python中新式类和经典类的区别
1).python在类中的定义在py2-3版本上是使用的有新式类和经典类两种情况,在新式类和经典类的定义中最主要的区别是在定义类的时候是否出现引用object;如:经典类:Class 类名::而新式类 ...
- Python新式类与经典类的区别
1.新式类与经典类 在Python 2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性:反之,即不由任意内置类型派生出的类 ...
- python中的__new__与__init__,新式类和经典类(2.x)
在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1 ...
- Python 新式类与经典类
新式类,经典类 查询匹配 广度查询 横着对每个类进行查询 深度查询 无视平级类,直接寻找下级类 #python 3.0 #新式类 广度查询 #经典类 广度查询 #python 2.0 #新式类 广度查 ...
- Python新式类和经典类的区别
@Python新式类和经典类的区别 class ClassicClass(): pass class NewStyleClass(object): pass x1 = ClassicClass() x ...
- Python类总结-继承-子类和父类,新式类和经典类
子类和父类 class Father(object): #子类在使用super调用父类时,Father后面要加object --新式类 def __init__(self): self.Fname = ...
- Python之面向对象新式类和经典类
Python之面向对象新式类和经典类 新式类和经典类的继承原理: 在Python3中,就只有新式类一种了. 先看Python3中新式类: 类是有继承顺序的: Python的类是可以继承多个类的,也就是 ...
随机推荐
- 【转】Graphics 关于呈现质量与合成模式
GDI+相关的作图,每种语言都有其自身的封装类,但本质上是一样的,下面这篇文章写的非常好,对于C#的Graphics类也是使用的,所以转载了,原文在这里: http://www.cnblogs.com ...
- kd-tree理论以及在PCL 中的代码的实现
(小技巧记录:博客园编辑的网页界面变小了使用Ctrl ++来变大网页字体) 通过雷达,激光扫描,立体摄像机等三维测量设备获取的点云数据,具有数据量大,分布不均匀等特点,作为三维领域中一个重要的数据来 ...
- JQ 获取地址栏参数
var cat_id = getParamValue("cat_id"); if(cat_id == null){ cat_id = 1; } $("#brand_cat ...
- [hadoop读书笔记] 第十五章 sqoop1.4.6小实验 - 将mysq数据导入HBASE
导入命令 sqoop import --connect jdbc:mysql://192.168.200.250:3306/sqoop --table widgets --hbase-create-t ...
- 6、Qt Meta Object system 学习
原文地址:http://blog.csdn.net/ilvu999/article/details/8049908 使用 meta object system 继承自 QOject 类定义中添加 Q_ ...
- About darwin OS
Darwin 是一种Unix-like操作系统,整合数种的技术,包含开 Darwin LOGO 放原始码的XNU核心,一种以微核心为基础的核心架构来实作Machkernel.操作系统的服务和userl ...
- 深入浅出 kvm qemu libvirt
在所谓的kvm技术中,应用到的其实有2个东西:qemu+kvmkvm负责cpu虚拟化+内存虚拟化,实现了cpu和内存的虚拟化,但kvm不能模拟其他设备:qemu是模拟IO设备(网卡,磁盘),kvm加上 ...
- 关于Unity中GrabPass截屏的使用和Shader的组织优化
GrabPass截屏 可以用来截屏,截屏后把纹理传给下一个通道使用. 1:使用抓屏通道, GrabPass {} 或 GrabPass { “ 纹理名称”}; 使用GrabPass {}后,可以用_G ...
- [转]Android精品开源项目整理
前言: 无论你是android的初学者,还有是android开发多年的高手,可能都会有很多想法和经验希望与人分享交流,渴望能够接触到更多的实战项目,正所谓所谓与高手论道才能互补所长,与英雄 ...
- 【Python】Python加lxml实现图片解析下载功能
1.下载网页:OpenHtml.py import urllib.request from urllib.parse import quote class HtmlLoader(object): de ...