1 . 偏函数 (partial)
from functools import partial
def func(*args,**kwargs):
a=args
b=kwargs
return a,b
new_func=partial(func,1,2,3,4,a=3,b=5)
ret=new_func()
print(ret)
最终得到的结果为: ( (1, 2, 3, 4) , {'a': 3, 'b': 5} )
我理解的意思为: 将1,2,3,4,a=3,b=5传入func中去执行函数.
其实就是 :往函数里传一个值不执行,返回一个新函数
2.ThreadingLocal线程安全 空间转时间
我们之前学的线程并发是这样的
from threading import Thread
import threading
class foo(object):
pass
f=foo()
def func(a):
f.num=a
time.sleep(1)
print(f.num,threading.current_thread().ident)
for i in range(10):
t=Thread(target=func,args=(i,))
t.start()
但是这样我们打印的结果为
原因是线程的创建速度是很快的(一瞬间),在第一个a进入函数执行时,睡眠了1秒,io切换到下一个时,又睡眠,直到最后一个进入函数,第一个a还在睡眠.当第一个结束睡眠的时候,num已经变成了最后一个值,所以每一个num都变成了最后一个数字9.
解决方法:(只要在类中继承一个local即可)
from threading import local
import threading
class Foo(local):
pass
f=Foo()
def func(i):
f.num=i
time.sleep(1)
print(f.num,threading.current_thread().ident)
for i in range(10):
t=Thread(target=func,args=(i,))
t.start()
3.myLocalStack
import time
from threading import Thread,local
import threading
class MyLocalStack(local):
stack={}
pass
mls=MyLocalStack()
def func(i):
a=threading.current_thread().ident
mls.stack[a]=[f'r{i+1}',f's{i+1}']
time.sleep(1)
print(mls.stack[a].pop(),mls.stack[a].pop(),a)
mls.stack.pop(a)
print(mls.stack,a)
if __name__ == '__main__':
for i in range(10):
t=Thread(target=func,args=(i,))
t.start()
4.RunFlask + request
视图函数 : 根据一个路由地址指向一个函数,这个函数就叫视图函数
app.run()的原理:
app.run()实际上执行的是app里面的run_simple方法,
而run_simple方法调用的是里面的__call__()方法,而__call__中返回了一个wsgi_app()方法
run_simple方法里面需要的参数有(host,port,func,**options)
参数:
host : 服务器的ip地址
port : 服务器端口
func : 当请求过来的时候,执行func函数
options : 传参参数
具体实例代码如下:
from werkzeug.serving import run_simple
from werkzeug.wrappers import Response,Request
@Request.application
def app(req):
if req.path == '/login':
return login(req)
return Response('200 OK')
def login(res):
return Response('欢迎来到登陆页面')
run_simple('127.0.0.1',8888,app)
req的意思就是request,他是werkzeug里面的用法,记住就行
5.请求上文
请求上文的意思是: 你怎么将app,request,session放进去的
首先我们要清楚,run方法实际上执行的是__call__方法,而通过源码我们发现__call__实际上返回的是一个wsgi_app的方法
返回到wsgi_app中
我们得到了ctx返回了一个request_context对象,对象里面有 --> app, request , session
最后得到结果: top是LocalStack中的top方法
到这里我们回顾之前一个学习的知识:
class Foo(object):
def __call__(self, *args, **kwargs):
print("我是可以执行的对象")
def __setattr__(self, key, value):
print(key,value)
def __getattr__(self, item):
print(item)
f=Foo()
#对象加括号 : 调用哪个__call__方法
f.num
#这里实际上执行的是__getattr__方法,如果我们在上面没有写这个函数,那么会报错
#以上打印的结果为 num
f.num=1
#这里实际上执行的是__setattr__方法
#以上打印的结果为 num , 1
所以在上面我们发现 _local.stack[-1] ,所以我们是不是要找_local是不是有__getattr__方法呀
所以最后我们得到的 top结果为 None.
最后返回的rv:
到这里,请求上文也就结束了
6.请求下文
请求下文是你怎么将app,request,session拿出来调用的
请求下文是在你执行视图函数的时候才开始运行的
请求下文是执行函数的时候,request.方法或者使用到session的时候才到了请求下文的内容
因为我们之前request.method 所以执行了__getattr__方法