单例
什么是单例?
单例模式是指:保证一个类仅有一个实例,并提供一个访问它的全局访问点
# 线程1 执行: cursor.excute('select * from user') # 线程2执行 cursor.excute('select * from books') # 线程1 执行 cursor.fetchAll() # 拿出查询到的数据 # django ,每个线程,一个连接对象---》 连接池
1. 使用模块
mysingleton.py:
class Singleton(object): def foo(self): pass singleton = Singleton()
将上面的代码保存在文件 mysingleton.py
from a import singleton # 不论在哪个py文件中导入singleton ,都是同一个singleton对象
2. 使用装饰器
1. 闭包函数是什么?
参数是传不进来的,是包进来的,用了它上层作用域范围的变量
-1. 定义在函数内部
-2. 对外部作用域有引用(如果使用外部的可变类型,直接使用,如果是不可变类型,需要使用nonlocal声明)
def add(): # a = 1 不可变类型 a = [1,2,3] # 可变类型,直接使用 def inner(): # nonlocal a 需要声明使用 a.append('ss') print('内部的值是:',a) inner() print('外部的值',a) add()
2. 装饰器是什么?
- 装饰器是闭包函数的一个典型应用,在实现不改变函数的源代码和调用方式的基础上,为函数增加新的功能
3. 装饰器的作用?
- 在实现不改变函数的源代码和调用方式的基础上,给函数增加新的功能
比如:
import time def time_total(func): def inner(*args, **kwargs): start = time.time() res = func(*args, **kwargs) end = time.time() print('运行时间是:', end - start) return res return inner @time_total # 原理就是 add=time_total(add) def add(a, b): time.sleep(2) return a + b res=add(2,3) # 现在是inner print(add.__name__) # 函数名
使用装饰器来实现单例:
### 2 方式二:使用装饰器 ## 之前学的 装饰器,都是用来装饰 函数 ,装饰器可以用来装饰类 def singleton(cls): instance = None def _singleton(*args, **kargs): nonlocal instance if not instance: instance = cls(*args, **kargs) return instance return _singleton @singleton # A=singleton(A) class A(): def __init__(self, x=0): self.x = x a1 = A(2) # 其实执行的是 singleton内部的闭包函数 _singleton() a2 = A(3) print(a1 is a2) # True
3. 使用类方法
## 方式三: 使用类方法 class Singleton(object): _instance = None def __init__(self): pass @classmethod def instance(cls, *args, **kwargs): if not cls._instance: cls._instance = cls(*args, **kwargs) return cls._instance a1 = Singleton.instance() # 对象=类.类的绑定方法 a2 = Singleton.instance() print(a1 is a2)
4. 基于new方法实现
### 方式四:使用 __new__ class Singleton(object): _instance = None def __init__(self): pass def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = object.__new__(cls) return cls._instance obj1 = Singleton() obj2 = Singleton() print(obj1 is obj2)
5. 基于metaclass方式实现
class SingletonType(type): _instance = None def __call__(cls, *args, **kwargs): if not cls._instance: cls._instance = object.__new__(cls) cls._instance.__init__(*args, **kwargs) return cls._instance class Foo(metaclass=SingletonType): def __init__(self, name): print('sdfasdf') self.name = name obj1 = Foo('name') obj2 = Foo('name') print(obj1 is obj2)
__init__ 和 __new__区别
1. 类()--->触发类中的__init__--->对象已经创建出来了,不能拦截住,做成单例了
2. 类()--->触发类中的__new__--->真正的创建对象,判断之前有没有创建过,如果创建过,直接返回
3. 懂了元类---》类()--->触发元类的 __call__--->断之前有没有创建过,如果创建过,直接返回
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号