1. 作用域
1.1 作用域
代码1
if 1 == 1: name = ‘alex‘ for i in range(10): name = i print(name) # Java/C# 不可以 # Python/JavaScript 可以 # Python中无块级作用域
代码2:函数
def func(): name = ‘alex‘ print(name) def func(): name = ‘alex‘ func() print(name) # Python中以函数为作用域
代码3:
name = ‘alex‘ def f1(): print(name) def f2(): name=‘eric‘ f1() f2() # Python的作用域在执行之前已经确
代码4:
name = ‘alex‘ def f1(): print(name) def f2(): name = ‘eric‘ return f1 ret = f2() ret() # Python作用域链,由内向外找,直到找不到报错
代码5:
li = [x+100 for x in range(10) if x>6] print(li)
代码6:
li = [lambda :x for x in range(10)] r = li[0]() print(r) # 剖析 # li类型:列表 # li列表中的元素:[函数, 函数, 函数...] # 函数在没有执行前,内部代码不执行 # li[0],lambda函数 # 函数(),执行函数 # 返回值:9
代码7:
li = [] for i in range(10): def f1(): return i li.append(f1) print(li[0]()) print(li[1]()) print(li[2]()) # 输出结果 # 9 # 9 # 9 li = [] for i in range(10): def f1(x=i): return x li.append(f1) print(li[0]()) print(li[1]()) print(li[2]()) # 输出结果 # 0 # 1 # 2
PS:本质上看代码是否执行
1.2 小结
- Python中无块级作用域
- Python中以函数为作用域
- Python作用域链,由内向外找,直到找不到报错
- Python的作用域在执行之前已经确定
1.3 Python多继承2.7版本与3.5版本
- Python 3所有的类都默认继承object,称新事类
- Python 2所有的类默认不继承object,称经典类
2. SocketServer及IO多路复用
2.1 socketserver基本执行过程
import socketserver class MyClass(socketserver.BaseRequestHandler): def handle(self): pass obj = socketserver.ThreadingTCPServer((‘127.0.0.1‘, 9999), MyClass) obj.serve_forever() # 创建socket对象 # accept 处理请求 # server_address = (‘127.0.0.1‘, 9999) # RequestHandlerClass = MyClass == () # self.RequestHandlerClass() = MyClass() == () # 1.obj封装了self.RequestHandlerClass = MyClass # 2.创建了socket, bind, lister
2.2 通过IO多路复用实多并发
概述:
IO多路复用不占用CPU
select,poll,epoll (支持所有IO操作,不支持文件操作)
监听socket对象内部是否变化了?
什么时候变化?连接或收发消息
服务器端的socket发生变化,表示有新连接来了
sk: 有新连接来了
conn: 要收发消息了
IO多路复:监听socket对象内部是否变化了
1) 多并发连接实现
server
import socket import select sk = socket.socket() sk.bind((‘127.0.0.1‘, 999, )) sk.listen(5) while True: rlist,w,e, = select.select([sk,], [], [], 1) #1为超时时间 print(rlist) # rlist中socket对象列表,[sk, ] # 有新连接 rlist = [sk] # 无连接 rlist = [] for r in rlist: print(r) conn, address = r.accept() conn.sendall(bytes(‘hello‘, encoding=‘utf-8‘))
client
import socket sk = socket.socket() sk.connect((‘127.0.0.1‘, 999, )) data = sk.recv(1024) print(data) while True: input(">>>") sk.close()
2) IO多路复用实现伪并发,可收发消息
Server
import socket import select sk = socket.socket() sk.bind((‘127.0.0.1‘, 999, )) sk.listen(5) inputs = [sk,] while True: rlist,w,e, = select.select(inputs, [], [], 1) #1为超时时间 print(len(inputs), len(rlist)) # 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,些时rlist值为[sk] # 监听conn对象,如果conn发生变化,表示客户端有新消息发送过来了,些时rlist的值为[客户端] # rlist中socket对象列表,[sk, ] # 有新连接 rlist = [sk] # 无连接 rlist = [] for r in rlist: if r == sk: # 新客户来连接 conn, address = r.accept() # conn是什么?其实也是socket对象 inputs.append(conn) conn.sendall(bytes(‘hello‘, encoding=‘utf-8‘)) else: # 有人给我发消息了 r.recv(1024)
Client
import socket sk = socket.socket() sk.connect((‘127.0.0.1‘, 999, )) data = sk.recv(1024) print(data) while True: inp = input(">>>") sk.sendall(bytes(inp, encoding=‘utf-8‘)) sk.close()
3) 读写分离实现
Server
import socket import select sk = socket.socket() sk.bind((‘127.0.0.1‘, 9998, )) sk.listen(5) inputs = [sk,] outputs = [] while True: rlist,wlist,e, = select.select(inputs, outputs, [], 1) #1为超时时间 print(len(inputs), len(rlist), len(wlist), len(outputs)) # 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,些时rlist值为[sk] # 监听conn对象,如果conn发生变化,表示客户端有新消息发送过来了,些时rlist的值为[客户端] # rlist中socket对象列表,[sk, ] # 有新连接 rlist = [sk] # 无连接 rlist = [] for r in rlist: if r == sk: # 新客户来连接 conn, address = r.accept() # conn是什么?其实也是socket对象 inputs.append(conn) conn.sendall(bytes(‘hello‘, encoding=‘utf-8‘)) else: # 有人给我发消息了 try: ret = r.recv(1024) if not ret: raise Exception(‘断开连接‘) else: outputs.append(r) except Exception as e: inputs.remove(r) # 所有给我发过消息的人 for w in wlist: w.sendall(bytes(‘response‘, encoding=‘utf-8‘)) #回复消息 outputs.remove(w) # 删除已回复消息的人
Client
import socket sk = socket.socket() sk.connect((‘127.0.0.1‘, 9998, )) data = sk.recv(1024) print(data) while True: inp = input(">>>") sk.sendall(bytes(inp, encoding=‘utf-8‘)) print(sk.recv(1024)) sk.close()
4) 回复收到的消息
Server
import socket import select sk = socket.socket() sk.bind((‘127.0.0.1‘, 9998, )) sk.listen(5) inputs = [sk,] outputs = [] messages = {} # del messages[alex] #删除alex的消息 # message = { # alex:[msg1, msg2, ] # eric:[msg1, msg2, ] # } while True: rlist,wlist,e, = select.select(inputs, outputs, [], 1) #1为超时时间 print(len(inputs), len(rlist), len(wlist), len(outputs)) # 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,些时rlist值为[sk] # 监听conn对象,如果conn发生变化,表示客户端有新消息发送过来了,些时rlist的值为[客户端] # rlist中socket对象列表,[sk, ] # 有新连接 rlist = [sk] # 无连接 rlist = [] for r in rlist: if r == sk: # 新客户来连接 conn, address = r.accept() # conn是什么?其实也是socket对象 inputs.append(conn) messages[conn] = [] conn.sendall(bytes(‘hello‘, encoding=‘utf-8‘)) else: # 有人给我发消息了 try: ret = r.recv(1024) if not ret: raise Exception(‘断开连接‘) else: outputs.append(r) messages[r].append(ret) except Exception as e: inputs.remove(r) del messages[r] # 所有给我发过消息的人 for w in wlist: msg = messages[w].pop() resp = msg + bytes(‘response‘, encoding=‘utf-8‘) w.sendall(resp) #回复消息 outputs.remove(w) # 删除已回复消息的wlist
Client
import socket sk = socket.socket() sk.connect((‘127.0.0.1‘, 9998, )) data = sk.recv(1024) print(data) while True: inp = input(">>>") sk.sendall(bytes(inp, encoding=‘utf-8‘)) print(sk.recv(1024)) sk.close()
ThredingTCPServer源码剖析
PS:所有查找都要遵循一切从原点开始
第3章 进程与线程
3.1 多线程多进程
概述:
1、一个应用程序,可以有多进程和多线程
2、默认:单进程,单线程
3、单进程,多线程
l IO操作,不占用CPU
多线程提高并发
l 计算性操作,占用CPU
多进程提高并发
4、GIL,全局解释器锁
小结:
- 多线程多进程的目的提供并发
- IO密集型:多线程
- 计算密集型:多进程
PS:IO操作,不占用CPU GIL,全局解释器锁
3.2 如何建立多线程
练习创建主线程,子线程
import threading t = threading.Thread(target=f1, args=(123,)) t.start() #不代表当前纯种会被立即执行 f1(111) #主线程
基本配置参数
import threading t = threading.Thread(target=f1, args=(123,)) t.setDaemon(True) # true,表示主线程不等此子线程 t.start() # 不代表当前纯种会被立即执行 t.join(5) # 表示主线程至此,等待....,直到子线程执行完毕 # 参数:表示主线程最多等待时间n秒 # f1(111) #主线程 print(‘end‘) print(‘end‘) print(‘end‘) print(‘end‘)
import socketserver class MyClass(socketserver.BaseRequestHandler): def handle(self):pass # 创建socket对象# accept 处理请求# server_address = (‘127.0.0.1‘, 9999)# RequestHandlerClass = MyClass == ()# self.RequestHandlerClass() = MyClass() == ()# 1.obj封装了self.RequestHandlerClass = MyClass# 2.创建了socket, bind, listerobj = socketserver.ThreadingTCPServer((‘127.0.0.1‘, 9999), MyClass)obj.serve_forever()
时间: 2024-07-29 15:14:04