python-黑魔法-python不一样的懒加载

懒加载

一.一般方式懒加载

1
2
3
4
5
6
7
8
9
10
11
12
13

class Singleton(object):
_instance=None

@classmethod
def instance(clz):
if clz._instance is None:
clz._instance=Singleton()
return clz._instance

print(Singleton.instance()==Singleton.instance())

# 弊端是直接Singleton()就不一样

二.__new__来实现懒加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Singleton(object):
def __new__(clz):
if not hasattr(clz,"_instance"):
clz._instance=super(Singleton,clz).__new__(clz)
return clz._instance

print(Singleton()==Singleton())
# 注意: __init__ 与 __new__区别与联系
# 1. 在调用__init__前是先调用__new__方法
# 2. __new__一定会有return
# 3. __new__可以自定义类的实例化
# 如:
class PositiveInteger(int):
def __new__(clz,value):
return super(PositiveInteger,clz).__new__(clz,abs(value))
i=PositiveInteger(-3)
# 4.__new__可以实现mateclass

三.new + mateclass实现懒加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class TypeSingleton(type):

def __new__(clz, name, base, attrs):
# 这里可用用super 即object来创建 ,也可以直接tpye创建类
clz._instance = type.__new__(clz, name, base, attrs)
return clz._instance

class Singleton(metaclass=TypeSingleton):
_instance = None

@classmethod
def instance(clz):
return clz._instance

print(Singleton.instance() == Singleton.instance())
#注意:
#1. object类是所有内的父类(包含type类)
#2. type类是所有实例的父类(object也是type类创建)

四.高阶写法 多线程下懒加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

import threading
lock=threading.Lock()


class Singleton(object):

def __new__(cls, *args, **kwargs):
if not hasattr(cls,"_instance"):
try:
lock.acquire()
if not hasattr(cls, "_instance"):
cls._instance=super(Singleton,cls).__new__(cls,*args, **kwargs)
finally:
lock.release()
return cls._instance

print(Singleton() == Singleton())
# 双重检查+单例