闭包: 函数嵌套函数 函数的返回值是一个函数 内部函数使用了外部函数的变量 造成数据不会被释放。
函数的参数是一个变量
def f(a): def f1(): print(a) return f1 f2 = f(2) f2() # 2
函数的参数是另外一个函数
def fn(f): def fn1(): f() return fn1 def a(): print('111') s = fn(a) s1 = s() print(s1)
内部函数无法直接修改外部函数的变量
def a(): num = 10 def b(): num = 20 print(num) print(num) b() print(num) a() # 10 20 10 内部函数无法直接修改外部函数的变量
内部函数如果想要修改外部函数的变量值 需要使用关键字 nonlocal
def a(): num = 20 def b(): nonlocal num num = 30 print(num) print(num) b() print(num) a() # 20 30 30
定义装饰器,相当于是下面的函数直接作为参数传递给闭包的函数
def fn(callback): print('我是外部的函数') def fn1(): print('我是内部的函数') callback() return fn1 @fn # 使用装饰器 def callback(): print('我是参数的函数啊') callback()
闭包的参数是一个函数 该函数内部还接受参数:
def f(call): num = 10 def b(a,b): c = call(a,b) print(c+num) # 30 return c+num return b @f def call(a,b): return a+b call(10,10)
多个执行器的使用:
def a(call): def b(): num = call() return num+1 return b def c(call): def d(): num = call() return num+2 return d @a @c def call(): return 10 e =call() print(e) # 13 先执行@c的这个装饰器将最后的结果 再给到@a的执行器再去执行
带有参数的装饰器
def func(flag): def fn(call): def b(a,b): if flag == '+': print('执行加法') elif flag == '-': print('执行减法') num = call(a,b) print(num) return b return fn @func("+") def add(a,b): return a+b @func("-") def cl(a,b): return a-b g = add(10,20) h = cl(20,10)
使用类装饰器:
class Students(object): def __init__(self,fun): self.fun=fun def __call__(self, *args, **kwargs): print('调用函数') self.fun() @Students def fn(): print('我是被调用的函数') # 调用函数 我是被调用的函数 fn() # 当函数被调用的时候 会执行 类中的__call__的这个方法 同时fn本身的这个函数也会被调用
web服务 框架开发:
import socket
import framewprk
# 创建服务器 ipv地址 tcp链接
tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 设置端口号复用
tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
# 绑定端口号
tcp_server_socket.bind(('',8000))
# 设置监听
tcp_server_socket.listen(128)
# 循环等待客户端链接
while True:
#建立链接后 获取的客户端的内容 new_socket为二进制 ip_prot=127.0.0.1 还有链接的号码
new_socket,ip_prot = tcp_server_socket.accept()
recv_data=new_socket.recv(4096)
print(recv_data)
print(len(recv_data)) # 长度725 每次都不固定
if len(recv_data) != 0: # 说明有建立链接
recv_content = recv_data.decode('utf-8')
print(recv_content) # 转化成了 请求报文的格式了
quest_path = recv_content.split(' ',2)[1]
print(quest_path) # / 或者 /index.html
if quest_path == '/':
quest_path = '/index.html'
if quest_path.endswith('.html'):
env = {"request_path":quest_path}
# 调用外部的框架来处理动态资源的请求
status,headers,response_body = framewprk.handle_request(env)
print(status,headers,response_body)
# 响应行
response_line = "HTTP/1.1 %s\r\n" %status
# 响应头
response_header = ""
for header in headers:
response_header+="%s:%s\r\n" % header
# 响应报文
response_data = (response_line+response_header+"\r\n"+response_body).encode('utf-8')
print(response_data)
# 发送给浏览器
new_socket.send(response_data)
# 关闭链接
new_socket.close()
else:
try:
with open('./'+quest_path,'rb') as file:
file.read()
except Exception as e:
with open("error.html", 'rb') as file:
file_data = file.read()
# 设置响应行
response_line = 'HTTP/1.1 200 OK\r\n'
# 设置响应头
response_header = "Server:PWS/1.0\r\n"
# 响应体
response_body = file_data
# 进行拼接 转化为二进制
response = (response_line + response_header + "\r\n").encode('utf-8') + response_body
# 给客户端响应消息
new_socket.send(response)
else:
# 设置响应行
response_line = 'HTTP/1.1 200 OK\r\n'
# 设置响应头
response_header = "Server:PWS/1.0\r\n"
# 响应体
response_body = file_data
# 进行拼接 转化为二进制
response = (response_line + response_header + "\r\n").encode('utf-8') + response_body
# 给客户端响应消息
new_socket.send(response)
finally:
# 关闭链接
new_socket.close()
Framewprk文件中的代码:
import time
#获取首页的数据
def index():
status="200 ok"
response_header = [("Server","PWS/1.1")]
# 返回死的数据 也就是返回当前的时间
# data = time.ctime()
# 这里是返回首页index的内容
with open('index.html','r',encoding='utf-8') as file: file_data = file.read()
data = time.ctime()
request_body=file_data.replace('{%content%}',data)
return status,response_header,request_body
def center():
pass
# 处理没有找到动态路径
def not_found():
status = '404 Not Found'
response_header = [("Server", "PWS/1.1")]
data = "not Found"
return status,response_header,data
# 定义路由表
router_list = [('/index.html',index),('/center.html',center)]
# 处理路由的函数
def handle_request(env):
request_path = env['request_path']
# if request_path == '/index.html':
# return index()
# else:
# return not_found()
# 上面的代码修改为下面的 key:index.htmll fun:index()
for key,fun in router_list:
if key == request_path:
return fun()
else:
return not_found()
使用装饰器来开发web框架:
import time router_list=[] #装饰器处理路由的问题 def router(path): def decorator(call): # 把对应的路由给添加进去 router_list.append((path,call)) # ('/index.html',index) def fn(): return call() return fn return decorator # 处理没有找到动态路径 def not_found(): status = '404 Not Found' response_header = [("Server", "PWS/1.1")] data = "not Found" return status,response_header,data @router('/index.html') def index(): def index(): status = "200 ok" response_header = [("Server", "PWS/1.1")] # 返回死的数据 也就是返回当前的时间 # data = time.ctime() # 这里是返回首页index的内容 with open('index.html', 'r', encoding='utf-8') as file: file_data = file.read() data = time.ctime() request_body = file_data.replace('{%content%}', data) return status, response_header, request_body # 处理路由的函数 def handle_request(env): request_path = env['request_path'] for key,fun in router_list: if key == request_path: return fun() else: return not_found()
给客户端返回JSON格式的字符串 并且数据是从mysql数据库中获取的
import time import pymysql import json #获取首页的数据 def index(): status="200 ok" response_header = [("Server","PWS/1.1")] # 返回死的数据 也就是返回当前的时间 # data = time.ctime() # 这里是返回首页index的内容 with open('index.html','r',encoding='utf-8') as file: file_data = file.read() data = time.ctime() request_body=file_data.replace('{%content%}',data) return status,response_header,request_body def center(): conn = pymysql.connect(host="localhost",port=3306,user="root",password="123456",database="test",charset="utf8") cursor = conn.cursor() sql = """select * from user;""" cursor.execute(sql) result = cursor.fetchall() # ((2, 'zs'), (3, 'hs'), (4, 'wq')) center_data_list=[{"id": row[0], "name": row[1]} for row in result] json_str = json.dumps(center_data_list) cursor.close() conn.close() status = "200 OK" response_header = [("server","pws/1.1")] return status,response_header,json_str # 处理没有找到动态路径 def not_found(): status = '404 Not Found' response_header = [("Server", "PWS/1.1")] data = "not Found" return status,response_header,data # 定义路由表 router_list = [('/index.html',index),('/center.html',center)] # 处理路由的函数 def handle_request(env): request_path = env['request_path'] # if request_path == '/index.html': # return index() # else: # return not_found() # 上面的代码修改为下面的 key:index.htmll fun:index() for key,fun in router_list: if key == request_path: return fun() else: return not_found()