python基础2026.7.23
静态Web服务器
HTTP协议
1.HTTP协议的介绍
- HTTP 协议的全称是 (HyperText Transfer Protocol),翻译过来就是超文本传输协议。
- 超文本是超级文本的缩写,是指超越文本限制或者超链接,比如:图片、音乐、视频、超链接等等都属于超文本。
- HTTP 协议的制作者是蒂姆・伯纳斯 - 李,1991 年设计出来的,HTTP 协议设计之前目的是传输网页数据的,现在允许传输任意类型的数据。
- 传输 HTTP 协议格式的数据是基于 TCP 传输协议的,发送数据之前需要先建立连接。
2.HTTP的作用
HTTP规定了游览器和Web服务器通信数据的格式,也就是说游览器和web服务器通信需要使用
http协议。
3.游览器访问Web服务器的通信过程
通信效果图:

4.小结
- HTTP 协议是一个超文本传输协议
- HTTP 协议是一个基于 TCP 传输协议传输数据的
- HTTP 协议规定了浏览器和 Web 服务器通信数据的格式
URL
1.URL的概念
URL的意思是统一资源定位符,通常理解就是网络资源地址,也就是我们常说的网址。

2.URL的组成
-
URL 的样子:
https://news.163.com/18/1122/10/E178J2O4000189FH.html -
URL 的组成部分:
-
① 协议部分:
https://(在http协议基础上进行了升级,增加安全机制 =》 443) -
http://(主流 =》 80)ftp://(上传下载 =》 FTP软件) -
② 域名部分:
news.163.com=> 转换为 IP 地址(有了 IP 地址就能找到这个计算机了) -
③ 资源路径部分:
/18/1122/10/E178J2O4000189FH.html(确认具体要访问服务器上的那个资源)
3.域名和URL扩展
域名:
地址就是IP地址的别名,它是用点进行分割使用英文字母和数字组成的名字,使用域名的目的就是方便的记住某台主机ip地址
URL的扩展:
https://news.163.com/hello.html?page=1&count=10
查询参数部分:
?page=1&count=10
参数说明:
?后面的 page 表示第一个参数,后面的参数都使用 & 进行连接
==》》?参数 => page = 1第一页,count = 10显示10条数据
4.小结
URL就是网络资源的地址,简称网址,通过URL能够找到网络中对应的资源数据。
URL组成部分
1.协议部分
2.域名部分
3.资源路径部分
4.查询参数部分
查看HTTP协议的通信过程
1.谷歌游览器开发者工具的使用
首先需要安装Google Chrome浏览器,然后Windows和Linux平台按F12调出开发者工具,macOS选择视图->开发者->开发者工具或者直接使用alt+command+i这个快捷键,还有一个多平台通用的操作就是在网页右击选择检查。

2.开发者工具里查看详细请求

![]()
HTTP 请求头(Request Headers) 的抓包截图,记录浏览器向服务端发起请求时,自动携带的各类客户端信息,下面分字段讲解:
基础通用请求头字段
- Accept 声明浏览器能接收的响应数据格式,示例里支持
text/html网页、xhtml 文档等资源类型。 - Accept-Encoding 告知服务端浏览器支持的压缩算法:
gzip、deflate、br,服务端可选择对应算法压缩数据,减少传输体积、加快加载速度。 - Accept-Language 浏览器偏好语言:优先简体中文
zh-CN,其次中文zh,q=0.9代表语言权重优先级。 - Cache-Control: max-age=0 强制不走本地缓存,向服务端请求最新资源。
- Connection: keep-alive 开启长连接,一次 TCP 连接可多次收发 HTTP 请求,不用每次请求都重复建立连接,提升访问效率。
红框重点字段
Host: guancha.gmw.cn
- 作用:标识本次请求要访问的目标域名
- 核心意义:一台服务器会托管多个网站(虚拟主机),服务器靠
Host字段区分请求到底访问站点里的哪一个域名,是 HTTP 请求必填头部。
User-Agent(截图只展示开头)
- 作用:浏览器身份标识,格式一般包含浏览器内核、操作系统版本、浏览器版本
- 服务端通过 UA 判断:用户设备是 Windows / 手机、使用什么浏览器,可做兼容性适配、访问统计、爬虫识别拦截。
Chrome 安全类请求头(sec - 开头)
这类是现代 Chrome 新增的安全字段,用来做跨域、请求来源管控:
sec-ch-ua:上报浏览器品牌、版本sec-ch-ua-mobile:标识是否为手机设备(?0代表 PC 端)sec-ch-ua-platform:上报操作系统为 WindowsSec-Fetch-*系列:标记请求类型(页面跳转 / 跨域请求等),帮助服务端做安全防护Upgrade-Insecure-Requests: 1:浏览器告诉服务端,优先使用 HTTPS 加密协议访问
总结
整张截图就是浏览器发起网页请求时,自动打包发给网站服务器的附加信息:
Host告诉服务器要访问哪个站点User-Agent告诉服务器自己的设备、浏览器信息- 其余字段协商压缩、语言、缓存、连接方式、安全策略。
HTTP请求报文分析
1.HTTP请求报文
HTTP请求报文是客户端(如浏览器)发送给服务器的数据包,它定义了客户端希望执行的操作。一个完整的HTTP请求报文由以下三部分组成:
- 请求行 (Request Line)
- 请求头 (Request Headers)
- 请求体 (Request Body) - 可选
1.1 请求行
请求行是报文的第一行,包含三个部分,用空格分隔:
- 请求方法 (Method):指定要对资源执行的操作。
- 请求目标 (Request Target):通常是URL的路径和查询字符串部分。
- HTTP版本 (HTTP Version):如 HTTP/1.1 或 HTTP/2。
示例: GET /index.html HTTP/1.1
1.2 HTTP请求方法(报文类型)
HTTP协议定义了多种请求方法,每种方法代表一种不同的操作意图。以下是几种最核心和常用的方法:
- GET
- 作用:从服务器获取(查询)指定资源。
- 特点:请求参数附加在URL之后(查询字符串),可以被缓存、收藏为书签,有长度限制。不应用于产生副作用的操作。
- 示例:获取网页、图片、API数据。
- POST
- 作用:向服务器提交(新增)数据,通常会导致服务器状态变化(如新建资源)。
- 特点:数据放在请求体中,更安全,无长度限制。不可缓存。
- 示例:提交表单、上传文件、登录。
- PUT
- 作用:向服务器上传(更新)指定资源的最新完整内容。
- 特点:幂等操作(多次执行结果相同)。
- 示例:更新用户完整信息。
- DELETE
- 作用:请求服务器删除指定的资源。
- 特点:幂等操作。
- 示例:删除一篇文章、一个用户。
- HEAD
- 作用:与GET方法类似,但服务器只返回响应头,不返回响应体。
- 特点:用于获取资源的元信息(如检查链接有效性、文件大小),节省带宽。
- PATCH
- 作用:对资源进行局部修改,而非完整替换。
- 特点:与PUT(完整替换)形成对比。
- 示例:只更新用户的邮箱地址。
1.3 请求头
请求头位于请求行之后,以键值对的形式传递关于请求或客户端的附加信息。我们在上一节“查看HTTP协议的通信过程”中已经详细分析过,例如:
Host: 目标主机和端口。User-Agent: 客户端软件信息。Accept: 客户端可接受的响应内容类型。Content-Type: 请求体的媒体类型(如application/json)。Authorization: 身份验证凭证。
1.4 请求体
请求体用于携带需要发送给服务器的数据,通常在POST、PUT、PATCH等方法中使用。其格式由Content-Type请求头指定。
- 常见格式:
- 表单数据:
application/x-www-form-urlencoded(如name=John&age=30) - 多部分表单数据:
multipart/form-data(用于文件上传) - JSON数据:
application/json(如{"name": "John", "age": 30}) - 纯文本:
text/plain
- 表单数据:
1.5 小结
HTTP请求报文是客户端与服务器通信的“指令单”。其中,请求方法(如GET、POST、PUT、DELETE等)定义了操作的核心意图,是区分不同“类型”请求报文的关键。理解这些方法及其适用场景,是进行Web开发和API设计的基础。
2.GET
2.1请求报文格式

---- 请求行 ----
GET /wp-content/uploads/2020/12/zm.svg HTTP/
1.1 # GET 请求方式 请求资源路径 HTTP 协议版本
---- 请求头 -----
Host: www.itcast.cn # 服务器的主机地址和端口号,默认是 80
Connection: keep-alive # 和服务端保持长连接
Upgrade-Insecure-Requests:1 # 让浏览器升级不安全请求,使用 https 请求
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
# 用户代理,也就是客户端的名称
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
# 可接受的数据类型
Accept-Encoding: gzip, deflate # 可接受的压缩格式
Accept-Language: zh-CN,zh;q=0.9 #可接受的语言
Cookie: pgv_pvi=1246921728; # 登录用户的身份标识
---- 空行 ----
2.2GET请求报文分析
GET / HTTP/1.1\r\n
Host: www.itcast.cn\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100
Safari/537.36\r\n
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,
*/*;q=0.8\r\n
Accept-Encoding: gzip, deflate\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
Cookie: pgv_pvi=1246921728; \r\n
\r\n (请求头信息后面还有一个单独的'\r\n'不能省略) => 空白行
备注说明:
- 每一行 HTTP 报文末尾都以
\r\n(回车换行)作为行结束符; - 所有请求头结束后,必须额外再加一组
\r\n,用来标识请求头部分结束、分隔请求头与请求体; - 本次 GET 请求无请求体,因此末尾这组
\r\n就是整个请求报文的结束标记。
分析:
| 请求头字段 | 取值 | 作用说明 |
|---|---|---|
Host: www.itcast.cn | 目标域名 | 服务器靠该字段区分一台主机上托管的多个网站,是 HTTP1.1 强制必填项,默认访问 80 端口 |
Connection: keep-alive | 保持长连接 | 一次 TCP 连接可多次发送 HTTP 请求,不用每次请求都重复三次握手建立连接,提升访问效率 |
Upgrade-Insecure-Requests: 1 | 允许协议升级 | 浏览器告知服务器:后续尽量把 HTTP 明文请求自动升级为 HTTPS 加密请求 |
User-Agent | 浏览器 + 系统标识 | 上报客户端操作系统(Mac OS X 10_12_4)、浏览器内核与 Chrome 版本,服务端可据此做兼容性适配、爬虫识别 |
Accept | 可接收响应格式 | 声明浏览器能解析网页、xml、图片等资源类型,q=代表优先级权重 |
Accept-Encoding: gzip, deflate | 支持的压缩算法 | 告知服务器可对响应数据使用这两种压缩格式,减小传输流量、加快加载速度 |
Accept-Language: zh-CN,zh;q=0.9 | 语言偏好 | 优先返回简体中文内容,其次是普通中文 |
Cookie: pgv_pvi=1246921728; | 身份标识 | 携带本地缓存的 Cookie,向服务器传递用户访问标识、登录态、浏览记录等信息 |
3.POST请求
3.1POST请求报文格式

---- 请求行 ----
POST /xmweb?host=mail.itcast.cn&_t=1542884567319 HTTP/1.1
# POST请求方式 请求资源路径 HTTP协议版本
---- 请求头 ----
Host: mail.itcast.cn # 服务器的主机地址和端口号,默认是80
Connection: keep-alive # 和服务端保持长连接
Content-Type: application/x-www-form-urlencoded # 告诉服务端请求的数据类型
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
# 客户端的名称
---- 空行 ----
---- 请求体 ----
username=hello&pass=hello # 请求参数
3.2POST请求报文分析
POST /xmweb?host=mail.itcast.cn&_t=1542884567319 HTTP/1.1\r\n
Host: mail.itcast.cn\r\n
Connection: keep-alive\r\n
Content-Type: application/x-www-form-urlencoded\r\n
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100
Safari/537.36\r\n
\r\n(请求头信息后面还有一个单独的'\r\n'不能省略)
username=hello&pass=hello
具体分析:
POST 报文结构:请求行 → 请求头 → 分隔空行(单独\r\n) → 请求体,和 GET 最大区别是 POST 携带请求体传参
1. 请求行解析
POST /xmweb?host=mail.itcast.cn&_t=1542884567319 HTTP/1.1
POST:请求方法,用于向服务器提交数据(登录、表单提交等场景),核心参数放在请求体,也可在 URL 拼接少量查询参数/xmweb:接口资源路径- URL 拼接参数:
host=mail.itcast.cn、_t=1542884567319(_t一般是时间戳,用来防缓存) HTTP/1.1:使用 HTTP1.1 协议,默认开启 TCP 长连接
2. 请求头逐字段说明
| 请求头 | 内容 | 作用 |
|---|---|---|
Host: mail.itcast.cn | 目标域名 | HTTP1.1 必填项,服务器靠它区分一台机器托管的多个站点,默认走 80 端口 |
Connection: keep-alive | 长连接 | 复用同一个 TCP 连接多次收发 HTTP 请求,省去反复三次握手的开销 |
Content-Type: application/x-www-form-urlencoded | 请求体格式声明 | 告知服务端:请求体是普通表单键值对格式,参数用&拼接,中文会做 url 编码,是网页表单最常用格式 |
User-Agent | 客户端标识 | 客户端系统为 Mac OS X 10_12_4,浏览器是 Chrome69 版本,服务端可做兼容适配、爬虫识别 |
3. 分隔空行:单独\r\n
HTTP 协议强制规范:所有请求头结束后,必须用一组\r\n分割请求头区域和请求体区域,省略会导致服务器无法解析报文结构。
4. 请求体:username=hello&pass=hello
- 按照
application/x-www-form-urlencoded格式组织,两个登录参数:用户名hello、密码hello - 这是 POST 核心传参位置,相比 URL 拼接参数,请求体数据不会暴露在浏览器地址栏、访问日志里,私密性更好
4.GET与POST请求报文小结
4.1 一个HTTP请求报文可以有请求行、请求头、空行和请求体 4个部分组成
4.2 请求行是由三部分组成:请求方式、请求资源路径、HTTP协议版本(1.1)
4.3 GET方式的请求报文没有请求体,只有请求行、请求头、空行组成
4.4 POST方式的请求报文可以有请求行、请求头、空行、请求体 四部分组成。
注意:POST方式可以允许没有请求体,但是这种格式很少见

5.响应报文分析(重点):响应头+响应数据

---- 响应行/状态行 ----
HTTP/1.1 200 OK # HTTP协议版本 状态码 状态描述
---- 响应头 ----
Server: Tengine # 服务器名称
Content-Type: text/html; charset=UTF-8
# 内容类型(响应的数据类型,image/png)
Connection: keep-alive # 和客户端保持长连接
Date: Fri, 23 Nov 2018 02:01:05 GMT # 服务端的响应时间
---- 空行 ----
---- 响应体 ----
<!DOCTYPE html><html lang="en"> ...</html>
# 响应给客户端的数据(html网页)
5.1响应头

响应头信息主要是告诉游览器的客户端应该如何处理我们返回的数据。
5.2响应数据:

6.HTTP响应状态码
是用于表示Web服务器响应状态的3位数字代码

搭建Python自带静态Web服务器
1.什么是静态Web服务器

2.搭建Python自带的静态Web服务器
windows创建方式:
2.1创建一个文件夹,然后把所有的资源文件都放入这个文件夹

2.2在DOS窗口使用cd命令切换到此目录
2.3使用python -m 命令创建静态Web服务器
python -m http.server 9000
示例:

-m表示运行包里面的模块,执行这个命令的时候,需要进入你自己指定静态文件的目录。
然后通过游览器就能访问对应的html文件了。
2.4访问Web静态服务器(http://127.0.0.1:9000/)

3.小结
静态Web服务器是为了发出请求的游览器提供静态文档的程序,搭建Python自带的Web服务器

使用python开发属于自己的Web服务器
web服务器 = TCP 服务器(七步走)+ HTTP协议(请求、响应)
1.开发步骤

2.返回固定页面的数据
#导入模块
import socket
#1.创建套接字对象
tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#设置端口复用
tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
#2.绑定IP与端口
tcp_server_socket.bind(('',8080))
#3.设置监听
tcp_server_socket.listen(128)
print("静态Web服务器启动成功!访问:http://127.0.0.1:8080")
while True:
#4.等待客户端连接(浏览器连接)
new_socket ,ip_port = tcp_server_socket.accept()
#5.接收消息(返回结果是一个HTTP请求报文)
client_request_data = new_socket.recv(1024).decode("utf-8")
print("========收到浏览器请求========")
print(client_request_data)
#6.读取html网页,指定编码防止乱码
with open(r'source\index.html','r',encoding="utf-8") as f:
data = f.read()
#6.1响应行
response_line = 'HTTP/1.1 200 OK\r\n'
#6.2响应头 添加字符集
response_header = 'Content-Type: text/html;charset=utf-8\r\n'
#6.3空行
#6.4响应体
response_body = data
# ✅重点!!拼接完整报文:头部 + 空行 + html页面内容
response_msg = response_line + response_header + '\r\n' + response_body
response_data = response_msg.encode("utf-8")
#发送完整响应报文
new_socket.send(response_data)
#7.关闭本次客户端连接,释放资源
new_socket.close()
本地示例:
1.将index.html文件放到.py同级目录

2.启动项目访问127.0.0.1:8080/index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<!-- 引入外部CSS,路径根据你的目录结构填写 -->
<link rel="stylesheet" href="../css/login.css">
</head>
<body>
<div class="login-box">
<h2 class="login-title">账号登录</h2>
<div class="item">
<label>用户名</label>
<input type="text" placeholder="请输入用户名" id="username">
</div>
<div class="item">
<label>密码</label>
<input type="password" placeholder="请输入登录密码" id="password">
</div>
<button class="login-btn" onclick="login()">立即登录</button>
</div>
<script>
function login(){
let username = document.getElementById("username").value.trim();
let password = document.getElementById("password").value.trim();
if(!username){
alert("请输入用户名");
return;
}
if(!password){
alert("请输入密码");
return;
}
// 此处后续可对接后端POST登录接口
alert("登录信息已提交:用户名:" + username);
}
</script>
</body>
</html>
后端将index.html读取反回给游览器

3.本地控制台请求信息

数据返回成功。
3.返回指定页面(返回index.html引用的login.css)
初始代码:
#导入socket模块
import socket
#创建程序执行入口
if __name__ == '__main__':
#1.创建套接字对象
tcp_server_socket =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#2.绑定IP和端口
tcp_server_socket.bind(('',8080))
#3.设置监听
tcp_server_socket.listen(128)
while True:
#4.等待客户连接
new_socket,ip_port = tcp_server_socket.accept()
#5.接收客户端发过来的请求(http结构请求报文)
recv_data = new_socket.recv(1024).decode('utf-8')
1.分析游览器请求

2.将资源路径"拿"出来实现指定页面
2.1观察游览器请求类型
type(recv_data)
控制台响应结果:为字符串类型<class 'str'>

2.2 把recv_data用split按空格进行切割拿到访问资源路径
request_line = recv_data.split(' ')
print(request_line)
返回结果:列表
![]()
注意:.split(' ',maxsplit=2)中maxplit可以定义切几刀
![]()
![]()
2.3通过列表下标拿到资源路径
request_path = request_line[1]
游览器访问拿到资源路径
![]()
完整代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<!-- 引入外部CSS,路径根据你的目录结构填写 -->
<link rel="stylesheet" href="css/login.css">
</head>
<body>
<div class="login-box">
<h2 class="login-title">账号登录</h2>
<div class="item">
<label>用户名</label>
<input type="text" placeholder="请输入用户名" id="username">
</div>
<div class="item">
<label>密码</label>
<input type="password" placeholder="请输入登录密码" id="password">
</div>
<button class="login-btn" onclick="login()">立即登录</button>
</div>
<script>
function login(){
let username = document.getElementById("username").value.trim();
let password = document.getElementById("password").value.trim();
if(!username){
alert("请输入用户名");
return;
}
if(!password){
alert("请输入密码");
return;
}
// 此处后续可对接后端POST登录接口
alert("登录信息已提交:用户名:" + username);
}
</script>
</body>
</html>
请求报文与响应报文的作用

发起请求:(访问)
![]()
响应数据:服务器端进行数据响应到前端渲染页面

FastAPI框架
概念:
FastAPI是一个现代的,快速(高性能)python web框架,基于标准的python类型提示,使用python3.6+构建API的web框架


搭建环境
fastapi安装方式:
安装FastAPI
FastAPI的安装通常需要Python 3.7或更高版本。可以通过pip工具直接安装FastAPI及其依赖。
pip install fastapi
(.venv) PS C:\Users\Administrator\PycharmProjects\WelcomeScreen\基础学习> pip install fastapi
Collecting fastapi
Downloading fastapi-0.139.2-py3-none-any.whl.metadata (26 kB)
Collecting starlette>=0.46.0 (from fastapi)
Downloading starlette-1.3.1-py3-none-any.whl.metadata (6.4 kB)
Collecting pydantic>=2.9.0 (from fastapi)
Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)
Collecting typing-extensions>=4.8.0 (from fastapi)
Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)
Collecting typing-inspection>=0.4.2 (from fastapi)
Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)
Collecting annotated-doc>=0.0.2 (from fastapi)
Downloading annotated_doc-0.0.4-py3-none-any.whl.metadata (6.6 kB)
Collecting annotated-types>=0.6.0 (from pydantic>=2.9.0->fastapi)
Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)
Collecting pydantic-core==2.46.4 (from pydantic>=2.9.0->fastapi)
Downloading pydantic_core-2.46.4-cp314-cp314-win32.whl.metadata (6.7 kB)
Collecting anyio<5,>=3.6.2 (from starlette>=0.46.0->fastapi)
Downloading anyio-4.14.2-py3-none-any.whl.metadata (4.6 kB)
Collecting idna>=2.8 (from anyio<5,>=3.6.2->starlette>=0.46.0->fastapi)
Downloading idna-3.18-py3-none-any.whl.metadata (6.1 kB)
Downloading fastapi-0.139.2-py3-none-any.whl (130 kB)
Downloading annotated_doc-0.0.4-py3-none-any.whl (5.3 kB)
Downloading pydantic-2.13.4-py3-none-any.whl (472 kB)
Downloading pydantic_core-2.46.4-cp314-cp314-win32.whl (2.0 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.0/2.0 MB 10.5 kB/s 0:02:52
Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB)
Downloading starlette-1.3.1-py3-none-any.whl (73 kB)
Downloading anyio-4.14.2-py3-none-any.whl (125 kB)
Downloading idna-3.18-py3-none-any.whl (65 kB)
Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB)
Downloading typing_inspection-0.4.2-py3-none-any.whl (14 kB)
Installing collected packages: typing-extensions, idna, annotated-types, annotated-doc, typing-inspection, pydantic-core, anyio, starlette, pydantic, fastapi
Successfully installed annotated-doc-0.0.4 annotated-types-0.7.0 anyio-4.14.2 fastapi-0.139.2 idna-3.18 pydantic-2.13.4 pydantic-core-2.46.4 starlette-1.3.1 typing-extensions-4.16.0 typing-inspection-0.4.2
[notice] A new release of pip is available: 26.0.1 -> 26.1.2
[notice] To update, run: python.exe -m pip install --upgrade pip
安装ASGI服务器
FastAPI需要一个ASGI服务器来运行,推荐使用Uvicorn或Hypercorn。以下是安装Uvicorn的命令:
pip install uvicorn
.venv) PS C:\Users\Administrator\PycharmProjects\WelcomeScreen\基础学习> pip install uvicorn
Collecting uvicorn
Downloading uvicorn-0.51.0-py3-none-any.whl.metadata (6.6 kB)
Collecting click>=7.0 (from uvicorn)
Downloading click-8.4.2-py3-none-any.whl.metadata (2.6 kB)
Collecting h11>=0.8 (from uvicorn)
Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)
Collecting colorama (from click>=7.0->uvicorn)
Downloading colorama-0.4.6-py2.py3-none-any.whl.metadata (17 kB)
Downloading uvicorn-0.51.0-py3-none-any.whl (73 kB)
Downloading click-8.4.2-py3-none-any.whl (119 kB)
Downloading h11-0.16.0-py3-none-any.whl (37 kB)
Downloading colorama-0.4.6-py2.py3-none-any.whl (25 kB)
Installing collected packages: h11, colorama, click, uvicorn
Successfully installed click-8.4.2 colorama-0.4.6 h11-0.16.0 uvicorn-0.51.0
[notice] A new release of pip is available: 26.0.1 -> 26.1.2
[notice] To update, run: python.exe -m pip install --upgrade pip
验证安装
安装完成后,可以通过以下命令验证FastAPI和Uvicorn是否安装成功:
python -c "import fastapi; print(fastapi.__version__)"
uvicorn --version

创建简单的FastAPI应用
以下是一个简单的FastAPI应用示例,保存为main.py:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
运行FastAPI应用
使用Uvicorn运行FastAPI应用:
uvicorn main:app --reload
main:app:main是Python文件名(不含.py),app是FastAPI实例的名称。--reload:启用热重载,适合开发环境。
在命令行进行运行:

访问应用
运行后,默认情况下应用会运行在http://127.0.0.1:8000。可以通过浏览器或工具如curl访问:
curl http://127.0.0.1:8000

可选依赖
如果需要额外的功能,可以安装可选依赖:
pip install fastapi[all]
这会安装所有可选依赖,包括数据库支持、模板渲染等。
FastAPI的基本使用
基本步骤:
1.导入模块
2.创建FastAPI框架对象
3.通过@app路由装饰器收发数据
4.运行服务器
代码实现:
#1.导入模块
#导入FastAPI类
from fastapi import FastAPI
#导入Response类,用于返回数据给游览器
from fastapi import Response
#导入uvicorn服务器模块,用于保持此文件一直运行(类似于while True)
import uvicorn
#2.创建FastAPI框架对象
app = FastAPI()
#3.通过@app路由装饰器收发信息
#路由 游览器请求 => 服务器响应对应关系
#接收游览器发送过来的请求
@app.get("source/index.html")
#响应数据给游览器
def main():
# 向上一层找到source目录
with open("../source/index.html", "rb") as f:
data = f.read()
return Response(data, media_type="text/html")
#4.运行服务器
#FastAPI对象
#绑定IP
#绑定端口号
uvicorn.run(app,host='127.0.0.1',port=9000)
通过FastAPI访问多个指定页面
路由装饰器的作用:

实际上通过路由装饰器 我们就可以让一个网页对应一个函数,也就是可以实现访问指定网页了。
示例代码:
from fastapi import FastAPI, Response
import uvicorn
import os
app = FastAPI()
# 当前脚本所在文件夹
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# 拼接路径
SOURCE_DIR = os.path.join(BASE_DIR, "source")
# 标准化路径,自动消除../
SOURCE_DIR = os.path.normpath(SOURCE_DIR)
print("静态资源目录:", SOURCE_DIR)
@app.get("/index.html")
def index():
file_path = os.path.join(SOURCE_DIR, "index.html")
print("要打开的文件:", file_path)
with open(file_path,'rb') as f:
data = f.read()
return Response(data,media_type='text/html')
@app.get("/gdp.html")
def gdp():
file_path = os.path.join(SOURCE_DIR, "gdp.html")
with open(file_path,'rb') as f:
data = f.read()
return Response(data,media_type='text/html')
if __name__ == '__main__':
uvicorn.run(app, host='127.0.0.1', port=8000)
游览器访问:127.0.0.1/index.html

进程
多任务的介绍
电脑的多任务

多个任务的优势
多任务同时执行可以大大提高程序执行任务
能利用现学知识不能让多个任务同时执行
多任务的概念
多任务是指在同一时间内执行多个任务,
例如:现在电脑安装的操作系统都是多任务操作系统,可以同时运行着多个软件。
多任务的两种表现形式
并发
在一段时间内交替去执行多个任务
例子:


并行
在一段时间内真正的同时一起执行多个任务
例子:

知识要点
1.使用多任务能充分利用CPU资源,提高程序的执行效率,让你的程序具备处理多个任务的能立。
2.多任务执行方式有两种方式:
并发:在一段时间内交替去执行多个任务。
并行:在一段时间内真正的同时一起执行多个任务
进程的介绍
程序中实现多任务的方式
在python中,想要实现多任务可以使用多进程来完成
进程的概念

进程是资源分配的最小单位,它是操作系统进行资源分配和调度运行的基本单位,通俗理解:一个正在运行的程序一个进程。例如:正在运行的qq,微信等 他们都是一个进程。

多进程的作用

思考:
途中是一个非常简单的程序,一旦运行hello.py这个程序,按照这个代码的执行顺序,func_a函数执行完毕之后才能执行func_b函数。如果可以让func_a和func_b同时运行,显然执行hello.py这个程序的效率会大大提升。

知识点
1.进程是资源分配的最小单位
2.多进程是python程序中实现多任务的一种方式,使用多进程可以大大提生效率
多进程完成多任务
进程的创建步骤(三步走)
1.导入进程包
import multiprocessing
2.通过进程创建进程对象
进程对象 = multiprocessing.Process()
3.启动进程执行任务
进程对象.start()
通过进程类创建进程对象:
进程对象= multiprocessing.Process(target=任务名)

#创建一个函数func_a()
import multiprocessing
import time
def func_a():
print('任务A')
time.sleep(3)
#创建一个函数func_b()
def func_b():
print('任务B')
time.sleep(3)
if __name__ == '__main__':
p1 = multiprocessing.Process(target=func_a)
p1.start()
p2 = multiprocessing.Process(target=func_b)
p2.start()
print('主进程结束')
输出结果:

进程执行带有参数的任务

args参数的使用

kwargs参数的使用

代码示例:
import multiprocessing
import time
def music(num):
for i in range(num):
print('听音乐')
time.sleep(0.2)
def coding(t):
for i in range(3):
print('代码')
time.sleep(t)
#定义程序的执行入口
if __name__ == '__main__':
#创建进程对象
music_process = multiprocessing.Process(target=music, args=(3,))
coding_process = multiprocessing.Process(target=coding, kwargs={'t': 3})
#启动进程执行多任务
music_process.start()
coding_process.start()
输出结果:

知识要点
进程执行带有参数的任务传参又两种方式:
1.元组方式传参:元组方式传参一定要和参数的顺序保持一致

2.字典方式传参:字典方式传参字典中的key一定要和参数名保持一致

获取进程编号
进程编号的作用:
当程序中进程的数量越来越多时,如果没有办法区分主进程和子进程还有不同的子进程,那么就无法进行有效的进程管理,为了方便管理实际上每个进程都是有自己编号的.
获取进程编号的两种方式:
-
获取当前进程编号获取当前父进程编号
打开任务管理器:切换到详细信息,会有每个进程的PID(进程编号)

2.当前父进程编号

3.os.getpid()的使用
代码示例:
import multiprocessing
import os
pid = os.getpid()
print("当前进程编号:", pid)
#或者
pid = multiprocessing.current_process().pid
print("当前进程编号:", pid)
输出效果:

4.父进程的编号
import multiprocessing
import os
def work():
print('执行work任务。。。')
#获取当前进程的编号id
pid = os.getpid()
print(f'work子进程的编号是:{pid}')
#获取当前进程的父进程编号
ppid = os.getppid()
print(f'work子进程的父进程编号是:{ppid}')
#定义程序的执行入口
if __name__ == '__main__':
print(f'主进程的编号:{os.getpid()}')
sub_process = multiprocessing.Process(target= work)
sub_process.start()
输出结果:

逻辑分析:
① 进程结构
- 主进程(父进程):运行
if __name__ == '__main__'内所有代码,PID =12456 - 子进程:调用
work()函数,PID =12457 - 子进程的父进程 ID = 主进程 PID,证明父子进程关系
② 关键 API 说明
-
os.getpid()获取当前正在执行这段代码的进程编号- 在
if __name__里调用 → 获取主进程 PID - 在
work()函数里调用 → 获取子进程 PID
- 在
-
os.getppid()获取当前进程的父进程编号- work 函数中执行,拿到创建它的主进程 PID
③ multiprocessing 重点规则(Windows 平台必看)
plaintext
if __name__ == '__main__':
这一行绝对不能省略! Windows 创建子进程时会重新导入模块,如果没有这个入口判断,代码会无限递归创建子进程,直接卡死。
④ 执行流程拆解
- 启动脚本,操作系统创建【主进程】,打印主进程 PID
multiprocessing.Process(...)只是创建进程对象,不会创建系统进程.start()调用 → 向操作系统申请,生成全新独立的【子进程】- 子进程启动,进入
work()函数执行,打印自身 PID、父进程 PID - work 执行完毕,子进程自动销毁;主进程继续运行
进程的os.kill()的使用
os.kill() 的基本用法
os.kill() 是 Python 中用于向进程发送信号的函数,属于 os 模块。通过传递进程 ID(PID)和信号编号,可以控制目标进程的行为。常见信号包括终止进程(SIGTERM)、强制终止(SIGKILL)等。
import os
import signal
# 向 PID 为 1234 的进程发送 SIGTERM 信号(优雅终止)
os.kill(1234, signal.SIGTERM)
常用信号类型
SIGTERM(15): 请求进程正常终止,允许进程清理资源。SIGKILL(9): 强制立即终止进程,无法被捕获或忽略。SIGINT(2): 中断信号(如 Ctrl+C),通常用于交互式终止。
# 强制终止进程
os.kill(1234, signal.SIGKILL)
获取进程 PID
在发送信号前,通常需要获取目标进程的 PID。可以通过 os.getpid()(当前进程)或外部工具(如 ps 命令)获取。
# 获取当前进程的 PID
current_pid = os.getpid()
os.kill(current_pid, signal.SIGTERM)
错误处理
如果目标 PID 不存在或无权限操作,os.kill() 会抛出 ProcessLookupError 或 PermissionError。建议使用 try-except 捕获异常。
try:
os.kill(99999, signal.SIGTERM) # 假设 PID 不存在
except ProcessLookupError:
print("进程不存在")
except PermissionError:
print("无权限操作该进程")
跨平台注意事项
- Unix/Linux/macOS: 支持所有标准信号。
- Windows: 仅支持
SIGTERM和CTRL_C_EVENT/CTRL_BREAK_EVENT,且实现有限。
替代方案
对于更复杂的进程管理,推荐使用 subprocess 模块或第三方库(如 psutil),提供更友好的接口。
import psutil
# 使用 psutil 终止进程
proc = psutil.Process(1234)
proc.terminate() # 发送 SIGTERM
proc.kill() # 发送 SIGKILL
知识要点

进程的注意点
1.进程之间不共享全局变量
实际上创建一个进程就是把主进程的资源进行拷贝产生了一个新的进程,这里的主进程和子进程是相互独立的

案例:
import multiprocessing
import time
from 模块.程序的执行入口 import main
#创建一个全局变量(主进程中的全局变量)
my_list = []
#创建一个任务,用于向my_list中添加数据
def write_data():
for i in range(3):
my_list.append(i)
print(f'add:{i}')
print(my_list)
#创建一个任务,用于从my_list中获取数据
def read_data():
print(f'read_data{my_list}')
if __name__ == '__main__':
#创建写入数据进程
write_process = multiprocessing.Process(target=write_data())
#创建读取数据进程
read_data = multiprocessing.Process(target=read_data())
#启动进程执行相关任务
write_process.start()
time.sleep(1)
read_data.start()
输出结果:进程之间资源独立

2.主进程默认不会等待所有的子进程执行结束再结果
主进程结束以后,子进程可能依然在运行
案例:
import multiprocessing
import time
def work():
for i in range(10):
print('工作中')
time.sleep(0.2)
if __name__ == '__main__':
#创建子进程
work_process = multiprocessing.Process(target=work)
work_process.start()
#让主进程等待1秒
time.sleep(1)
print('主进程执行完成了')
输出结果: 主进程默认不会等待所有的子进程执行结束再结果

解决办法一:设置守护进程
#设置守护主进程,主进程退出后子进程直接销毁,不再执行子进程中的代码
work_process.daemon = True

代码示例:
import multiprocessing
import time
#工作函数
def work():
for i in range(10):
print('工作中')
time.sleep(0.2)
if __name__ == '__main__':
#创建子进程
work_process = multiprocessing.Process(target=work)
#设置守护主进程,主进程退出后子进程直接销毁,不再执行子进程中的代码
work_process.daemon = True
#启动子进程
work_process.start()
#主进程延迟1s
time.sleep(1)
print('主进程执行完毕')
输出结果: 设置守护主进程,主进程退出后子进程直接销毁,不再执行子进程中的代码

解决方案二:销毁子进程
#让子线程直接销毁,表示终止执行,主进程退出之前,把所有的子进程直接销毁就可以了
work_process.terminate()
代码示例:
import multiprocessing
import time
#工作函数
def work():
for i in range(10):
print('工作中')
time.sleep(0.2)
if __name__ == '__main__':
#创建子进程
work_process = multiprocessing.Process(target=work)
#启动子进程
work_process.start()
#主进程延迟1s
time.sleep(1)
#让子线程直接销毁,表示终止执行,主进程退出之前,把所有的子进程直接销毁就可以了
work_process.terminate()
print('主进程执行完毕')
输出结果:让子线程直接销毁,表示终止执行,主进程退出之前,把所有的子进程直接销毁就可以了

更多推荐



所有评论(0)