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

如下:

源码:

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单例模式在新式类和经典类中的区别。的更多相关文章

  1. python之继承、抽象类、新式类和经典类

    一.上节补充1.静态属性静态属性 : 类的属性,所有的对象共享这个变量 如果用对象名去修改类的静态属性:在对象的空间中又创建了一个属性,而不能修改类中属性的值 操作静态属性应该用类名来操作 例1:请你 ...

  2. python中新式类和经典类

    python中的类分为新式类和经典类,具体有什么区别呢?简单的说, 1.新式类都从object继承,经典类不需要. Python 2.x中默认都是经典类,只有显式继承了object才是新式类 Pyth ...

  3. python中新式类和经典类的区别

    1).python在类中的定义在py2-3版本上是使用的有新式类和经典类两种情况,在新式类和经典类的定义中最主要的区别是在定义类的时候是否出现引用object;如:经典类:Class 类名::而新式类 ...

  4. Python新式类与经典类的区别

    1.新式类与经典类 在Python 2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性:反之,即不由任意内置类型派生出的类 ...

  5. python中的__new__与__init__,新式类和经典类(2.x)

    在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1 ...

  6. Python 新式类与经典类

    新式类,经典类 查询匹配 广度查询 横着对每个类进行查询 深度查询 无视平级类,直接寻找下级类 #python 3.0 #新式类 广度查询 #经典类 广度查询 #python 2.0 #新式类 广度查 ...

  7. Python新式类和经典类的区别

    @Python新式类和经典类的区别 class ClassicClass(): pass class NewStyleClass(object): pass x1 = ClassicClass() x ...

  8. Python类总结-继承-子类和父类,新式类和经典类

    子类和父类 class Father(object): #子类在使用super调用父类时,Father后面要加object --新式类 def __init__(self): self.Fname = ...

  9. Python之面向对象新式类和经典类

    Python之面向对象新式类和经典类 新式类和经典类的继承原理: 在Python3中,就只有新式类一种了. 先看Python3中新式类: 类是有继承顺序的: Python的类是可以继承多个类的,也就是 ...

随机推荐

  1. Android——indexof()

    Java中字符串中子串的查找共有四种方法(indexof()) Java中字符串中子串的查找共有四种方法,如下:1.int indexOf(String str) :返回第一次出现的指定子字符串在此字 ...

  2. linux Nginx服务开机自启

    linux Nginx服务开机自启 Nginx 是一个很强大的高性能Web和反向代理服务器.虽然使用命令行可以对nginx进行各种操作,比如启动等,但是还是根据不太方便.下面介绍在linux下安装后, ...

  3. poj 1723 中位数

    最近在看一些中位数的东西,然后顺便也看了些题目.poj 1723不仅要求到水平位置的最短距离和,还要求水平都相邻的排成一排的最短距离和,即士兵都站成一列. 到y轴的距离好办,按y轴坐标排序,求中位数, ...

  4. 安卓程序代写 网上程序代写[原]BluetoothDevice详解

    一. BluetoothDevice简介 1. 继承关系 public static Class BluetoothDevice extends Object implement Parcelable ...

  5. SQL server 分页方法小结

    这里面介绍一下常用的分页方法: 1.使用top来分页 select top @pageSize * from table where id not in (select top @pageSize*( ...

  6. Ubuntu 安装IntelliJ IDEA

    1. 下载IDEA    官网地中:http://www.jetbrains.com/idea/download/index.html    选择对应操作系统的版本.下载后,我的文件名称为: idea ...

  7. 纯CSS3实现的顶部社会化分享按钮

    今天要分享一款纯CSS3实现的社会化分享按钮,它放置在网页的顶部,你可以选择将它固定在网页顶部,这样对用户分享内容就十分方便.这些社会化分享按钮的图标文件来自google和bootstrap的字体文件 ...

  8. thinkphp 配置加载

    状态配置 每个应用都可以在不同的情况下设置自己的状态(或者称之为应用场景),并且加载不同的配置文件. 举个例子,你需要在公司和家里分别设置不同的数据库测试环境.那么可以这样处理,在公司环境中,我们在入 ...

  9. css 边框使用

    https://www.cnblogs.com/luka/p/5677241.html 1. 应用边框样式 先从控制边框样式的属性开始.简单边框有三个关键属性:border-width.border- ...

  10. Microsoft VBScript 运行时错误 错误 '800a0046' 没有权限 解决方法

    首先看看是不是scrrun.dll 设置了拒绝权限(在windows/system32目录,右键文件,添加 IUSR+机器名 账户).... 一.如果您的系统提示"没有找到scrrun.dl ...