python之路_flask框架_单例模式及session原理

实例化补充:

一、单例模式

1、单例模式介绍

  单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。常见有如下四种单例模式:

单例模式1:模块

  模块是天然的单例模式,因为在模块的第一次调用后会编译成.pyc文件,在以后的调用过程中会会直接加载.pyc文件。

单例模式2:类@classmethod

(1)无法支持多线程情况:

class Singleton(object):

    def __init__(self):
        #模拟io阻塞
        import time
        time.sleep(1)
    @classmethod
    def instance(cls,*args,**kwargs):
        if not hasattr(Singleton,"_instance"):
            Singleton._instance=Singleton(*args,**kwargs)
        return Singleton._instance
#应用
obj1=Singleton.instance()
obj2=Singleton.instance()
print(obj1,obj2)  #<__main__.Singleton object at 0x000002C49DB6C5F8> <__main__.Singleton object at 0x000002C49DB6C5F8>

(2)支持多线程情况

import threading
class Singleton(object):
    _instance_lock=threading.Lock()
    def __init__(self):
        import time
        time.sleep(1)

    @classmethod
    def instance(cls,*args,**kwargs):
        if not hasattr(Singleton,"_instance"):
            with Singleton._instance_lock:
                if not hasattr(Singleton,"_instance"):
                    Singleton._instance=Singleton(*args,**kwargs)
        return Singleton._instance

#应用
def task(n):
    obj=Singleton.instance()
    print(n,obj)
    
for i in range(10):
    t=threading.Thread(target=task,args=[i,])
    t.start()

单例模式3:基于__new__

(1)不支持多线程情况

class Singleton(object):
    def __init__(self):
        pass
    def __new__(cls, *args, **kwargs):
        if not hasattr(Singleton,"_instance"):
            Singleton._instance=object.__new__(cls,*args,**kwargs)
        return Singleton._instance
    
#应用:类实例化时会首先去执行__new__方法
obj=Singleton()

(2)支持多线程情况

import threading
class Singleton(object):
    _instance_lock=threading.Lock()
    def __init__(self):
        import time
        time.sleep(1)
    def __new__(cls, *args, **kwargs):
        if not  hasattr(Singleton,"_instance"):
            with Singleton._instance_lock:
                if not hasattr(Singleton,"_instance"):
                    Singleton._instance=object.__new__(cls,*args,**kwargs)
        return Singleton._instance
        
#应用:类实例化时会首先去执行__new__方法
def task(n):
    obj=Singleton()
    print(n,obj)
for i in range(10):
    t=threading.Thread(target=task,args=[i,])
    t.start()

单例模式4:基于metaclass

  分析如下:

"""
1.对象是类创建,创建对象时候类的__init__方法自动执行,对象()执行类的 __call__ 方法
2.类是type创建,创建类时候type的__init__方法自动执行,类() 执行type的 __call__方法(类的__new__方法,类的__init__方法)

# 第0步: 执行type的 __init__ 方法【类是type的对象】
class Foo:
    def __init__(self):
        pass

    def __call__(self, *args, **kwargs):
        pass

# 第1步: 执行type的 __call__ 方法
#        1.1  调用 Foo类(是type的对象)的 __new__方法,用于创建对象。
#        1.2  调用 Foo类(是type的对象)的 __init__方法,用于对对象初始化。
obj = Foo()
# 第2步:执行Food的__call__ 方法
obj()
"""

  单例模式实例:

import threading
class SingletonType(type):
    _instance_lock = threading.Lock()
    def __call__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            with SingletonType._instance_lock:
                if not hasattr(cls, "_instance"):
                    cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)
        return cls._instance

class Foo(metaclass=SingletonType):
    def __init__(self,name):
        self.name = name
obj1
= Foo('name') obj2 = Foo('name') print(obj1,obj2)

2、单例模式应用

  这里主要针对我们上一章节讲的数据库连接池,将其与单例模式进行结合,使得任何用户或者视图在调用数据库的时候,不需要反复实例化数据库连接池对象,主要介绍如下:

import pymysql
import threading
from DBUtils.PooledDB import PooledDB

class SingletonDBPool(object):
    _instance_lock = threading.Lock()

    def __init__(self):
        self.pool = PooledDB(
            creator=pymysql,
            maxconnections=6, 
            mincached=2, 
            maxcached=5,  
            maxshared=3,
            blocking=True, 
            maxusage=None, 
            setsession=[], 
            ping=0,
            host='127.0.0.1',
            port=3306,
            user='root',
            password='123',
            database='pooldb',
            charset='utf8'
        )

    def __new__(cls, *args, **kwargs):
        if not hasattr(SingletonDBPool, "_instance"):
            with SingletonDBPool._instance_lock:
                if not hasattr(SingletonDBPool, "_instance"):
                    SingletonDBPool._instance = object.__new__(cls, *args, **kwargs)
        return SingletonDBPool._instance

    def connect(self):
        return self.pool.connection()

  上述数据库连接池的单例模块的引用的实例如下:

def run():
    pool = SingletonDBPool()               #实例化
    con = pool.connect()                   #创建连接
    # .........

    con.close()                            #关闭,不是真正的关闭

if __name__ == '__main__':
    run()

二、自定义session

  参考文档:https://python-team.gitbooks.io/flask-doc/content/di-si-zhang-kuo-zhan/11-nei-zhisession-yuan-li.html

posted @ 2018-02-01 19:15  骑猪走秀  阅读(918)  评论(0编辑  收藏  举报