• 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

  • 相关阅读:
    IE下PNG透明图片fadeIn出现黑边的问题
    愿闻其翔记(一)
    简单的日期选择器
    HTML5 贪吃蛇
    HTML5小程序,变化的色彩
    HTML5 Canvas 基本图形画法
    帝国CMS实现一二级导航及其高亮
    php中json_decode()和json_encode()
    JavaScript重复元素处理
    JQuery在光标位置插入内容
  • 原文地址:https://www.cnblogs.com/seven-007/p/8400091.html
Copyright © 2020-2023  润新知