闭包: 函数嵌套函数 函数的返回值是一个函数 内部函数使用了外部函数的变量 造成数据不会被释放。
函数的参数是一个变量
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()










