本节内容:
课前准备知识:
函数嵌套函数的使用方法:
我们在使用函数嵌套函数的时候,是学习装饰器的时候,出现过,由一个函数返回值是一个函数体情况。
我们在使用函数嵌套函数的时候,最好也这么写。
1 def test(): 2 name=2 3 def test1(): 4 print(name) 5 return test1 6 7 8 test()()
通过返回值调用嵌套函数。或者你想执行函数test1的函数体,也可以如下操作但是不建议这么做。
1 def test(): 2 name=2 3 def test1(): 4 print(name) 5 test1() 6 7 test()
一:作用域:
a)在python中无块级作用域。在JavaScript 和python一样,没有块作用域,在C#和java中有块级作用域,变量只能在一个代码块中生效。
1 for i in range(9): 2 name=i 3 print(name) 4 8
1 if True: 2 name='ok' 3 print(name) 4 ok
b)python有函数作用域。外部不能调用函数内的变量。
1 def test(): 2 name=2 3 print(name)##name拿不到变量name的值。
即时函数执行也拿不到
1 def test(): 2 name=2 3 test() 4 print(name)
c)作用域链:函数从自己的作用域由内往外(上)找直至找到变量,如果没有会报错。
1 name=1 2 def test(): 3 name=2 4 def test1(): 5 name=3 6 print(name) 7 return test1 8 9 test()() 10 3
1 name=1 2 def test(): 3 name=2 4 def test1(): 5 print(name) 6 return test1 7 8 9 test()() 10 2
1 name=1 2 def test(): 3 def test1(): 4 print(name) 5 return test1 6 7 8 test()() 9 1
如上3个例子,说明函数是从自己的函数域找相应的变量,如果没有就外层函数找,外层函数没有,会去上层找,直至找到为止。
调用内部函数的变量由作用域1 到作用域2 到作用域3的顺序查找。
d)python在执行前作用域已经确定了,当解释器从上到下对代码的加载的时候,作用域已经确定了。所以在别的函数调用其他函数的时候,作用域需要去原先的函数作用域中找。
1 def test(): 2 name='tom' 3 print(name) 4 5 6 def func(): 7 name='evil' 8 test() 9 10 11 func() 12 tom
e)列表的推到式。
列表生成:
1 li=[x for x in range(6) if x >2]##由后面的for循环if选值生成列表。for前面是生成什么样的列表。 2 print(li) 3 [3, 4, 5]
li=[lambda :x for x in range(5)]
易错点:函数没被调用,只会生成提一些列函数,而变量x是形参。而不是实参。
根据列表的推导式,生成没有被执行的lambda表达式,也就是函数。也就是说li里的对象是函数对象。由于只有调用函数的时候才能执行函数体有。所以li[0]()在执行的时候,由于变量x在函数里内没有赋值,会在函数体外面找,外面x的值已经为4.
1 li=[lambda :x for x in range(5)] 2 print(li) 3 ret=li[1]() 4 print(ret) 5 6 [<function <listcomp>.<lambda> at 0x0000000000A91510>, <function <listcomp>.<lambda> at 0x0000000000A91730>, <function <listcomp>.<lambda> at 0x0000000000A917B8>, <function <listcomp>.<lambda> at 0x0000000000A91840>, <function <listcomp>.<lambda> at 0x0000000000A918C8>] 7 4
1 li=[] 2 for x in range(5): 3 def f1(): 4 return x 5 li.append(f1) 6 7 print(li[0]()) 8 print(li[1]()) 9 print(li[2]())
如上代码在解释器执行的时候,从上到下,到函数f1 的时候, 没有执行return x的操作,所以生成列表是带有形参的x的函数对象。
本质上就是是否执行。
1 li=[] 2 for x in range(5): 3 def f1(x=x): 4 return x 5 li.append(f1) 6 7 print(li[0]()) 8 print(li[1]()) 9 print(li[2]()) 10 0 11 1 12 2
解释器从上到下,加载的时候,遇到函数的时候,只是把函数名字以及函数参数执行(f1(x=x)),函数体并不执行。
二:类在2.5的多继承。
![](data:image/png;base64,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)
说明:F 是继承D、E,然后D继承B E继承C B和C继承A的关系。
在python2中,如果最顶层的类(A)不继承(object)那么子类F找自己没有的方法是从自己到左边一直到A 然后在右边到C
在python3中所有的类默认继承object,如果在python2中最顶层的类中继承object的情况下的话,在子类找相应的方法的顺序和3中是一样的。
三:IO多路复用:
用socketserver写的程序,是由事件驱动程序,事件是:接收和发送请求。
传统编程和事件驱动程序的对比:
开始--->代码块A--->代码块B--->代码块C--->代码块D--->......--->结束
每一个代码块里是完成各种各样事情的代码,但编程者知道代码块A,B,C,D...的执行顺序,唯一能够改变这个流程的是数据。输入不同的数据,根据条件语句判断,流程或许就改为A--->C--->E...--->结束。每一次程序运行顺序或许都不同,但它的控制流程是由输入数据和你编写的程序决定的。如果你知道这个程序当前的运行状态(包括输入数据和程序本身),那你就知道接下来甚至一直到结束它的运行流程。
对于事件驱动型程序模型,它的流程大致如下:
开始--->初始化--->等待
与上面传统编程模式不同,事件驱动程序在启动之后,就在那等待,等待什么呢? 等待被事件触发。传统编程下也有“等待”的时候,比如在代码块D中,你定义了一个input(),需要用户输入数据。但这与下面的等待不同,传统编程的 “等待”,比如input(),你作为程序编写者是知道或者强制用户输入某个东西的,或许是数字,或许是文件名称,如果用户输入错误,你还需要提醒他,并 请他重新输入。事件驱动程序的等待则是完全不知道,也不强制用户输入或者干什么。只要某一事件发生,那程序就会做出相应的“反应”。这些事件包括:输入信 息、鼠标、敲击键盘上某个键还有系统内部定时器触发。
![](data:image/png;base64,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)
如上图所示,当客户端请求发送到服务端,服务端通过IO多路复用来监控服务端的socket的变化,来接收和发送请求,而server运行咱们自定义的handle方法来执行咱们的代码,并无限死循环执行下去,来抓取客户端的请求和发送给客户端请求。
四:IO多路复用(input\outp):
IO操作:我理解是:可以是一次磁盘的读写,也可以是一次请求处理。
IO多路复用实现:
通过select 、poll 、epoll来实现。
那在socketserver是如何通过IO多路复用来实现,不停的抓取客户请求以及收发客户端消息呢?
IO多路复用通过监听socketserver服务器的socket对象内部是否发生变化来实现多并发处理客户端请求。
那在什么情况下,socket对象发生变化呢?
1:服务端socket对象创建新的连接(创建新的socket对象来和客户端进行通信。)
2:和客户端socket进行通信的socket对象收发消息。
也就是说,服务端socket对象发生一次IO请求的时候,就发生一次变化。通过这个变化来实现多并发处理客户端请求。
通过select模式来实现简单的多并发请求:
服务器端:
1 import socket 2 import select 3 BUFF_SIZE=1024 4 IP_PORT=('0.0.0.0',9999) 5 SO=socket.socket() 6 SO.bind(IP_PORT) 7 SO.listen(5) 8 while True: 9 rlist,w,e=select.select([SO,],[],[],1) 10 print(rlist)
rlist,w,e=select.select([SO,],[],[],1)
通过select模块,给select函数传入参数,传入参数为3个列表,最后数字1,表示超时时间,表示select监听socket的变化超时为1秒,第一个形参添加是服务器socket的SO的变化,该函数的返回值是三个分别被rlist,w,e分别接收,而且返回值对象为一个列表。
当客户端没有请求的时候,rlist的列表为[],当有返回值的时候,rlist列表为socket对象的列表。类似为:[<socket.socket fd=224, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 9999)>]
客户端:
1 import socket 2 S=socket.socket() 3 S.connect(('127.0.0.1',9999))
简单的发送消息,看下是否有阻塞问题,如果没有select的话 socket服务器在同一时间只能接收一个请求。
服务端:
1 import socket 2 import select 3 BUFF_SIZE=1024 4 IP_PORT=('0.0.0.0',9999) 5 SO=socket.socket() 6 SO.bind(IP_PORT) 7 SO.listen(5) 8 while True: 9 rlist,w,e=select.select([SO,],[],[],1) 10 print(len(rlist)) 11 for i in rlist: 12 conn,addr=i.accept() 13 conn.sendall(bytes('OK',encoding='utf-8'))
客户端:
1 import socket 2 S=socket.socket() 3 S.connect(('127.0.0.1',9999)) 4 while True: 5 data=S.recv(1024) 6 print(data) 7 S=input('>')#用input等待用户输入来保持连接存在。 8 S.close()
效果:
实验一:
服务端:
客户端:
由以上实验,可以看到通过select模式监听客户端请求的时候,客户端的请求并没有出现阻塞。而服务端的rlist的列表,当监听的socket发生的变化的时候,rlist的长度为1,如果建立好连接的时候,rlist的列表的长度为0。
如果服务端没有建立连接是什么情况的呢?
实验二:
![](https://images2015.cnblogs.com/blog/959846/201607/959846-20160715143300545-2063652034.png)
由上图的所做的实验一和实验二,可以得到如下结论:
1:可以通过IO多路复用select模式,可以并发接收客户端请求。
2:在select模式的发现客户端请求的时候,如果服务端没去建立连接select的rlist列表,会一直存在这个变化的socket。
3:服务端和客户端创建连接的时候,rlist列表会自动去除该已经建立连接的socket对象。开始监听下一个客户端的请求。
服务端的for循环一直在循环,只有当rlist的列表不为空的时候,才执行for循环的循环体。
上面的例子只是监控服务端的socket的,而客户端的socket的并没有加入监听。下面把和客户端的通信的socket加入监控中。
服务端:
1 import socket 2 import select 3 BUFF_SIZE=1024 4 IP_PORT=('0.0.0.0',9999) 5 SO=socket.socket() 6 SO.bind(IP_PORT) 7 SO.listen(5) 8 9 NEW_LIST=[SO] 10 while True: 11 rlist,w,e=select.select(NEW_LIST,[],[],1) 12 print(len(rlist),len(NEW_LIST)) 13 for i in rlist: 14 if i==SO:##如果是新的连接的话,建立连接。 15 conn,addr=i.accept() 16 conn.sendall(bytes('OK',encoding='utf-8')) 17 NEW_LIST.append(conn)##把跟客户端的建立连接的socket添加到监听的cocket的列表中。 18 else:#处理客户端的socket发生变化的进行接收消息和发送消息。 19 i.recv(1024) 20 i.sendall(bytes('back',encoding='utf-8'))
客户端:
1 import socket 2 S=socket.socket() 3 S.connect(('127.0.0.1',9999)) 4 while True: 5 data=S.recv(1024) 6 print(data) 7 inp=input('>') 8 S.sendall(bytes(inp,encoding='utf-8'))
注意上面的服务端 我们是把建议连接之后,把服务端的跟客户端通信的conn append到列表中。
在select模式中,如果服务端的socket发生变化的话 ,会把这个socket对象加入到rlist列表中,如果有服务端对该socket做出了相应的响应(IO操作)rlist会把该socket对象删除掉。
如果服务器没有对变化的socket做出回应,rlist会一直有该socket对象!!!
如下所示:
服务端:
客户端:
服务端在建立连接之后,收发一次消息之后,客户端在发一次消息的时候,服务端没有响应。所以rlist一直有这个socket对象。也就是是告诉服务器端有一次(IO)请求未处理。
如上:通过for循环来依次处理客户端的请求,其实是一个伪并发。实际socketserver内部也是这么处理请求。
如果客户端断开连接,由于监听的NEW_LIST是我们程序进行append,在断开连接的时候,需要把相应跟客户端进行通信的socket进行remove。
服务端:
1 import socket 2 import select 3 BUFF_SIZE=1024 4 IP_PORT=('0.0.0.0',9999) 5 SO=socket.socket() 6 SO.bind(IP_PORT) 7 SO.listen(5) 8 9 NEW_LIST=[SO] 10 while True: 11 rlist,w,e=select.select(NEW_LIST,[],[],1) 12 print(len(rlist),len(NEW_LIST)) 13 for i in rlist: 14 if i==SO:##如果是新的连接的话,建立连接。 15 conn,addr=i.accept() 16 conn.sendall(bytes('OK',encoding='utf-8')) 17 NEW_LIST.append(conn)##把跟客户端的建立连接的socket添加到监听的cocket的列表中。 18 else:#处理客户端的socket发生变化的进行接收消息和发送消息。 19 try: 20 data=i.recv(1024) 21 i.sendall(bytes('back',encoding='utf-8')) 22 except Exception : 23 NEW_LIST.remove(i)##断开连接我们需要把对应的socket对象从我们监控列表中删除掉。 24 continue
在服务器断开连接的时候,默认客户端会发送一个空(这个没测出来,有待商榷。测试的时候并没有发送一个空)
1 import socket 2 import select 3 BUFF_SIZE=1024 4 IP_PORT=('0.0.0.0',9999) 5 SO=socket.socket() 6 SO.bind(IP_PORT) 7 SO.listen(5) 8 9 NEW_LIST=[SO] 10 while True: 11 rlist,w,e=select.select(NEW_LIST,[],[],1) 12 print(len(rlist),len(NEW_LIST)) 13 for i in rlist: 14 if i==SO:##如果是新的连接的话,建立连接。 15 conn,addr=i.accept() 16 conn.sendall(bytes('OK',encoding='utf-8')) 17 NEW_LIST.append(conn)##把跟客户端的建立连接的socket添加到监听的cocket的列表中。 18 else:#处理客户端的socket发生变化的进行接收消息和发送消息。 19 try: 20 data=i.recv(1024) 21 if not data: 22 print('oop') 23 raise Exception ('connect is over!')##断开并没有执行该语句。 24 i.sendall(bytes('back',encoding='utf-8')) 25 except Exception as e: 26 print(e) 27 NEW_LIST.remove(i) 28 continue
实现读写分离:
服务端:
1 import socket 2 import select 3 BUFF_SIZE=1024 4 IP_PORT=('0.0.0.0',9999) 5 SO=socket.socket() 6 SO.bind(IP_PORT) 7 SO.listen(5) 8 9 INPUTS=[SO] 10 OUPUTS=[] 11 while True: 12 rlist,wlist,e=select.select(INPUTS,OUPUTS,[],1) 13 #wlist列表表示谁给我发送过消息,outputs有值,wlist就有值。 14 print(len(rlist),len(INPUTS),len(OUPUTS),len(wlist)) 15 for i in rlist: 16 if i==SO:##如果是新的连接的话,建立连接。 17 conn,addr=i.accept() 18 INPUTS.append(conn)##把跟客户端的建立连接的socket添加到监听的cocket的列表中。 19 else:#处理客户端的socket发生变化的进行接收消息和发送消息。 20 try: 21 data=i.recv(1024) 22 if not data: 23 raise Exception ('connect is over!')##断开并没有执行该语句。 24 else: 25 OUPUTS.append(i)#把给服务端发送过消息的加入这个列表。 26 except Exception as e: 27 print(e) 28 INPUTS.remove(i) 29 continue 30 for w in wlist: 31 w.sendall(bytes('send again',encoding='utf-8')) 32 OUPUTS.remove(w)#发送完消息,需要把该socket对象移除,否则会无限发送消息。
客户端:
1 import socket 2 S=socket.socket() 3 S.connect(('127.0.0.1',9999)) 4 while True: 5 inp=input('>') 6 S.sendall(bytes(inp,encoding='utf-8')) 7 data=S.recv(1024) 8 print(data) 9 S.close()
鉴于上次客户端发的消息内容,回复客户端相同的内容。
1 import socket 2 import select 3 BUFF_SIZE=1024 4 IP_PORT=('0.0.0.0',9999) 5 SO=socket.socket() 6 SO.bind(IP_PORT) 7 SO.listen(5) 8 MSG={}#接收消息的字典。 9 INPUTS=[SO] 10 OUPUTS=[] 11 while True: 12 rlist,wlist,e=select.select(INPUTS,OUPUTS,[],1) 13 #wlist列表表示谁给我发送过消息,outputs有值,wlist就有值。 14 print(len(rlist),len(INPUTS),len(OUPUTS),len(wlist)) 15 for i in rlist: 16 if i==SO:##如果是新的连接的话,建立连接。 17 conn,addr=i.accept() 18 INPUTS.append(conn)##把跟客户端的建立连接的socket添加到监听的cocket的列表中。 19 else:#处理客户端的socket发生变化的进行接收消息和发送消息。 20 try: 21 data=i.recv(1024) 22 if not data: 23 raise Exception ('connect is over!')##断开并没有执行该语句。 24 else: 25 OUPUTS.append(i)#把给服务端发送过消息的加入这个列表。 26 MSG[i]=[] 27 MSG[i].append(data)##把客户端发送的消息添加到MSG字典当中。 28 except Exception as e: 29 print(e) 30 INPUTS.remove(i) 31 del MSG[i]##在断开连接的时候,需要该socket的所有消息去掉。 32 continue 33 for w in wlist: 34 msg=MSG[w].pop() 35 send_msg=msg+bytes('send again',encoding='utf-8') 36 w.sendall(send_msg) 37 OUPUTS.remove(w)#发送完消息,需要把该socket对象移除,否则会无限发送消息。
1 import socket 2 S=socket.socket() 3 S.connect(('127.0.0.1',9999)) 4 while True: 5 inp=input('>') 6 S.sendall(bytes(inp,encoding='utf-8')) 7 data=S.recv(1024) 8 print(data) 9 S.close()
epoll、select、poll:三种都是系统底层检测socket变化。
select是Windows和linux都有的一种IO多路复用的模式。
select:
1:多平台使用。
2:内部维护的一个for循环来监听服务器端socket的变化,效率很低。
3:select监听socket对象有个数的限制(1024个。)
poll:
1:内部还是for循环实现监听服务端socket的变化。
2:监听的对象个数没有限制。
epoll:
内部不在改变使用for循环使用。而是通过客户端的socket发生变化,主动告知epoll发生变化,效率更高。nginx就是采用这种模式处理IO。
这三种模式,可以检测不仅仅是检测socket对象,可以检测所有的IO操作(不支持文件操作),比如输入终端(键盘、crt等)、
五:socketserver源码剖析:
5-1
socketserver工作原理:
1:创建socket,通过IO多路复用(select)来监听服务器端socket的变化(新连接的建立、建立socket和客户端进行通信)。
2:创建多个线程处理客户端请求,在处理的过程执行我们定义的handle方法。
如上是一个请求的连接的进入和处理整个socketserver的处理流程。
代码:
1 import socketserver 2 class Myclass(socketserver.BaseRequestHandler): 3 def handle(self): 4 pass 5 6 7 8 9 if __name__=='__main__': 10 server=socketserver.ThreadingTCPServer(('0.0.0.0',9999),Myclass) 11 server.serve_forever()
首先来看第10行,第10行初始化ThreadingTCPServer一个对象,传入2个参数('0.0.0.0',9999)、Myclass。
首先需要执行ThreadingTCPServer的__init__()构造方法,由图5-1可以看到,只有TCPServer和BaseServer有构造方法,如下:
TCPServer构造方法:
由上可以看出在执行TCPServer的同时,执行他的父类BaseServer的__init__()构造方法。传入RequestHandlerClass类,这里RequestHandlerClass=Myclass(我们自定义的类。)
如下 是BaseServer的__init__()构造方法:
可以看出BaseServer执行构造方法,赋值了4个普通字段。其中self.RequestHandlerClass=RequestHandlerClass=Myclass
BaseServer构造方法执行完毕,执行TCPServer的构造方法:
1:首先创建一个socket。
2:执行server_bind()方法。
3:执行server_activeate()方法。
然后看下server_bing()方法执行了什么?
绑定server_address,而server_adress是我们程序中:
IP和PORT的元组,也就是说该步是服务端绑定监听端口。
执行server_activeate()方法,执行了什么呢?
创建客户端连接可排队等待连接池。
如上是初始化ThreadingTCPServer一个对象所执行的操作。
也就说:该步执行了,服务端socket的建立。
代码的10行执行完。
代码:
代码执行了什么呢?
由5-1图所示,只有类:BaseServer有方法server_forerver()。
由上图可以看见server_forerver()中执行了,IO多路复用(select)来对服务端的socket进行监听“变化”。
如果返回的read值为真执行self._hand_request_noblock()方法。由5-1图可以看出只有BaseServer有这个方法。如下:
如上所示,该方法执行self.get_request()方法,由5-1所示只有TCPServer有该方法。
有上所示,该方法执行accpet方法来接收客户端的请求,并赋值给request,client_address所以贯穿整个程序的self.request是服务端跟客户端进行通信的套接字。
也就是说上面操作已经建立好连接、并监控服务端的socket的变化。等待客户端的请求连接。
接下来交给多线程并发处理我们的请求。
我们来看下方法:process_request方法执行了什么?
由5-1图可以看到:
只有类:ThreadingMixIn有process_request方法。如下:
如上所示:该方法创建线程,并执行方法:process_request_thread
我们来一起看下该方法执行了什么。该方法也在ThreadingMixIn类中。
该方法执行了finish_request方法。由5-1图可以看到:BaseServer类中有该方法:
如上所示执行构造RequestHandlerClass这个类对象。由上面我们推导我们知道:
self.RequestHandlerClass=RequestHandlerClass=Myclass
也就是说执行我们定义的类Myclass的构造方法,由于我们定义的没有构造方法,那执行父类BaseRequestHandler方法.
由上可以看出来,该构造方法执行了self.setup以及 self.handle方法,由于我们没有定义self.setup,所以只执行:self.handle
而我们定义的类中有该方法,也就是执行我们自定义的handle方法。
由上可以得出:
建立完连接,socketserver创建多线程,并执行我们自定义的handle方法。
也就是socketserver说整个过程包括:
1:建立好连接、并监控服务端的socket的变化。等待客户端的请求连接。
2:建立完连接,socketserver创建多线程,并执行我们自定义的handle方法。
如上是socketserver的源码剖析~!
五:多线程:
在python中程序处理包括:
1:一个应用程序可以是多线程、多进程。
2:默认是单进程、单线程。
3:单进程多线程:IO操作不占用cpu。使用多线程提高并发。
4:计算性操作,占用CPU,用多进程提高并发。
在python中GIL(全局解释器锁),只能在同一时间只能有一个线程跟cpu交互。在java和C#中没有这个限制,可以单进程多个线程进行cpu交互计算。
多线程举例:
1 #!/usr/bin/env python 2 import time 3 def f1(arg, t=None): 4 if t: 5 t._delete() 6 time.sleep(5) 7 print(arg) 8 9 10 # for i in range(10): 11 # f1(i) 12 # 单进程、单线程的应用程序 13 import threading 14 t1 = threading.Thread(target=f1, args=(1,)) 15 #t.setDaemon(True) # true,表示主线程不等此子线程,注意这个是线程设置,需要start之前定义 16 t1.start()# 不代表当前线程会被立即执行 17 #t.join(2) # 表示主线程到此,等待 ... 直到子线程执行完毕, 18 # 参数,表示主线程在此最多等待n秒 19 20 t2 = threading.Thread(target=f1, args=(2,t1)) 21 t2.start()# 不代表当前线程会被立即执行 22 print('end') 23 print('end') 24 print('end') 25 print('end') 26 print('end')
t1 = threading.Thread(target=f1, args=(1,))中target表示做什么操作,args表示传入什么参数,如果没有参数的话,需要传入一个空元组。
单独join(超时间)使用的时候,不和setDaemon使用的话,会等待超时之后,执行下面的代码,配合使用是等待超时之后执行下面代码就结束主线程,不等子线程执行完。。