• 九 .Flask上下文管理 前戏知识点 local 和 偏函数 面向对象 栈


    一  上下文管理  前戏知识点 local 和 偏函数 面向对象  栈

    1. local

    local多个线程修改同一个数据,复制多份变量给每个线程用,
    比如我们用的request,怎样让不同的请求有自己的request。就是为每个线程开辟一块空间进行数据存储

      threading.local【和flask无任何关系】
      作用:为每个线程创建一个独立的空间,使得线程对自己的空间中的数据进行操作(数据隔离)。

      不用threading.local

    from threading import Thread
    import time
    ctx = -1
    def task(arg):
        global ctx
        ctx = arg
        # time.sleep(2)
        print(ctx)
    
    for i in range(5):
        t = Thread(target=task,args=(i,))
        t.start()
    
    # 0
    # 1
    # 2
    # 3
    # 4

     使用threading.local

    from threading import Thread,local
    # 特殊的对象
    ctx = local()
    def task(arg):
        ctx.value = arg
        # time.sleep(2)
        print(ctx.value)
    for i in range(5):
        t = Thread(target=task,args=(i,))
        t.start()
    
        # 0
        # 1
        # 2
        # 3
        # 4
    import threading
    from threading import local
    def task(i):
        print(threading.get_ident(),i)    #  获取每个线程唯一id
    
    for i in range(5):
        t = threading.Thread(target=task,args=(i,))
        t.start()
        
    # 14896 0
    # 10780 1
    # 3356 2
    # 11384 3
    # 14308 4
    import threading
    from threading import local
    import time
    obj = local()
    def task(i):
        obj.xxxxx = i
        print(threading.get_ident(), obj.xxxxx,"拉拉")
        time.sleep(2)
        # print(obj.xxxxx,i)
        print(threading.get_ident(),i,"哈哈")
    
    for i in range(5):
        t = threading.Thread(target=task,args=(i,))
        t.start()
    # 6232 0 拉拉
    # 4348 1 拉拉
    # 7084 2 拉拉
    # 972 3 拉拉
    # 6560 4 拉拉
    # 6232 0 哈哈
    # 6560 4 哈哈
    # 972 3 哈哈
    # 4348 1 哈哈
    # 7084 2 哈哈
    
    
       通过字典自定义threading.local(函数) 方法一
      根据字典自定义一个为每个协程开辟空间进行存取数据。
    import time
    import threading
    import greenlet
    DIC = {}
    def task(i):
        # ident = threading.get_ident()
        ident = greenlet.getcurrent()
        if ident in DIC:
            DIC[ident]['aa'] = i
        else:
            DIC[ident] = {'aa':i }
        time.sleep(2)
    
        print(DIC[ident]['aa'],i)
    
    for i in range(5):
        t = threading.Thread(target=task,args=(i,))
        t.start()
        print(DIC)

    面向对象版

    from threading import Thread,get_ident
    class Local(object):
        storage = {}
        def get(self,k):
            ident = get_ident()
            return Local.storage[ident][k]
    
        def set(self,k,v):
            ident = get_ident()
            if ident in Local.storage:
                Local.storage[ident][k] = v
            else:
                Local.storage[ident] = {k:v}
    obj = Local()
    def task(arg):
        obj.set('val',arg)
        v = obj.get('val')
        print(v)
    
    for i in range(10):
        t = Thread(target=task,args=(i,))
        t.start()

    兼容线程和协程(源码到request中去看,看local的__getattr__,setattr)

    - 通过getattr/setattr 构造出来 threading.local的加强版(协程)

    import time
    import threading
    try:
        import greenlet
        get_ident =  greenlet.getcurrent
    except Exception as e:
        get_ident = threading.get_ident
    
    class Local(object):
        DIC = {}
    
        def __getattr__(self, item):
            ident = get_ident()
            if ident in self.DIC:
                return self.DIC[ident].get(item)
            return None
    
        def __setattr__(self, key, value):
            ident = get_ident()
            if ident in self.DIC:
                self.DIC[ident][key] = value
            else:
                self.DIC[ident] = {key:value}
    obj = Local()
    
    def task(i):
        obj.xxxxx = i
        time.sleep(2)
        print(obj.xxxxx,i)
    
    for i in range(10):
        t = threading.Thread(target=task,args=(i,))
        t.start()

     2. 偏函数(functoots.partial)

    import functools
    
    
    def index(a1,a2):
        return a1 + a2
    
    # 原来的调用方式
    # ret = index(1,23)
    # print(ret)
    
    # 偏函数,帮助开发者自动传递参数
    new_func = functools.partial(index,5)
    ret = new_func(1)
    print(ret)

     3.面向对象 执行父类方法  和    面向对象中特殊的方法

    class Base(object):
    
        def func(self):
            print('Base.func父亲')
    
    class Foo(Base):
        def func(self):
            # 方式一:根据mro的顺序执行方法
            # super(Foo,self).func()
    
            # 方式二:主动执行Base类的方法
            Base.func(self)
            print('Foo.func儿子')
    
    obj = Foo()
    obj.func()
    
    # Base.func父亲
    # Foo.func儿子
    class Base(object):
        def func(self):
            super(Base, self).func()
            print('Base.func')
    
    class Bar(object):
        def func(self):
            print('Bar.func1111111')
    
    class Foo(Base,Bar):
        pass
    
    # 示例一
    obj = Foo()
    obj.func()
    print(Foo.__mro__)
    
    # Bar.func1111111
    # Base.func
    # (<class '__main__.Foo'>, <class '__main__.Base'>, <class '__main__.Bar'>, <class 'object'>)
    
    
    
    # 示例二  报错没有这个方法  AttributeError: 'super'对象没有属性'func'
    # obj = Base()
    # obj.func()
    class Foo(object):
        def __init__(self):
            # self.storage = {}
            object.__setattr__(self,'storage',{})
    
        def __setattr__(self, key, value):
            print(key,value,self.storage)
    
    obj = Foo()
    obj.xx = 123

    # xx 123 {}
    __getitem__       __setitem__   __delitem__

    class
    Foo(object): def __getitem__(self, item): print(item,"11") def __setitem__(self, key, value): print(key,value,"22") def __delitem__(self, key): print(key,"333") obj = Foo() obj['k1'] obj["aa"] obj['k1'] = 123 del obj['k1'] # k1 11 # aa 11 # k1 123 22 # k1 333


    class Test(object):
        def __init__(self ,name):
            self.name = name
        def __getattr__(self, value):
            if value == 'address':
                return 'China111'
    
    if __name__=="__main__":
        test = Test('letian')
        print (test.name)
        print (test.address)
        test.address = 'Anhui'
        print (test.address)
    
    
    # letian
    # China111
    # Anhui
    
    
    
    # 如果是调用了一个类中未定义的方法,则__getattr__也要返回一个方法,例如:
    
    class Test(object):
        def __init__(self, name):
            self.name = name
    
        def __getattr__(self, value):
            return len
    
    
    if __name__ == "__main__":
        test = Test('letian')
        print(   test.getlength('letian'))
    # 6 
     isinstance===>>>MethodType和isinstance和Type函数
    
    def func():
        pass
    
    
    class Foo(object):
    
        def func(self):
            pass
    
    # 执行方式一
    # obj = Foo()
    # obj.func() # 方法
    
    # 执行方式二
    # Foo.func(123) # 函数
    
    from types import FunctionType,MethodType
    
    # 通过实例化方法 func是一个方法
    obj = Foo()
    print(isinstance(obj.func,FunctionType)) # False
    print(isinstance(obj.func,MethodType))   # True
    
    # 通过类名判断 func 是函数 不是方法
    print(isinstance(Foo.func,FunctionType)) # True
    print(isinstance(Foo.func,MethodType))   # False
    __slots__ 
    
    class Foo(object):
        # __slots__ = ('name',)
        def __init__(self):
            self.name = '111'
            self.age = 18
    
    
    obj = Foo()
    print(obj.name)
    print(obj.age)
    
    # 111
    # 18
    
    
    
    
    class Foo(object):
        __slots__ = ('name',)
        def __init__(self):
            self.name = 'alex'
            # self.age = 18
    
    
    obj = Foo()
    print(obj.name)
    # print(obj.age)
    
    # 111
    # by luffycity.com
    
    DATA = {
        'request': {
            'method': "GET",
            'form': {}
        },
        'session': {
            'user': '哈哈哈哈',
            'age': "19"
        }
    }
    class LocalProxy(object):
        def __init__(self, key):
            self.key = key
    
        def get_dict(self):
            return DATA[self.key]
    
        def __str__(self):
            return 'asdf'
    
        def __getattr__(self, item):
            data_dict = self.get_dict()
            aa=111
            return data_dict[item],aa
    
        def __getitem__(self, item):
            data_dict = self.get_dict()
            return data_dict[item]
    
        def __add__(self, other):
            return other + 1
    
    
    request = LocalProxy('request')
    session = LocalProxy('session')
    
    
    print(request.method)
    print(request.form)
    
    print(session.user)
    print(session.age)
    执行:
    # ('GET', 111)
    # ({}, 111)
    # ('哈哈哈哈', 111)
    # ('19', 111)
    # Process finished
    class Foo(object):
    
        def __str__(self):
            return 'asdf'
    
        def __getattr__(self, item):
            return "999"
    
        def __getitem__(self, item):
            return '87'
    
        def __add__(self, other):
            return other + 1
    
    obj = Foo()
    
    print(obj)
    print(obj.x)
    print(obj['x1'])
    print(obj + 7)
    
    执行:
    asdf
    999
    87
    8

    4. 栈

    class Stack(object):
    
        def __init__(self):
            self.data = []
    
        def push(self,val):
            self.data.append(val)
    
        def pop(self):
            return self.data.pop()
    
        def top(self):
            return self.data[-1]
    
    _stack = Stack()
    
    _stack.push('李四')
    _stack.push('王五')
    
    print(_stack.pop())
    print(_stack.pop())
    #王五
    #李四
  • 相关阅读:
    SELECT IDENT_CURRENT(tableName)和自增长列的纠结
    [置顶]c# 设计模式(1)一 创建型
    我们互联网生活因家庭服务器改变
    互联网创业不妨先放下平台梦
    影响未来的应用ifttt,互联网自主神经系统的又一个有力证据
    什么是ifttt,ifttt怎么玩? ifttt操作体验具体步骤
    杰出企业家的20个好习惯
    折叠分组表格中重用Cell导致的问题
    使用AChartEngine画折线图
    MSSQL获取当前插入的ID号及在高并发的时候处理方式
  • 原文地址:https://www.cnblogs.com/lovershowtime/p/11747169.html
Copyright © 2020-2023  润新知