九 .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())
#王五
#李四
原文地址:https://www.cnblogs.com/lovershowtime/p/11747169.html