恭喜你,一路闯关到这里!现在你的Python程序已经能处理文件、并发任务,还能用数据库持久化存储数据了。但它们都还像一个个“单机游戏”。接下来,我们要给你的程序插上“网线”,让它们能通过网络与外界通信,甚至变成一个其他人能访问的网站。
本章我们将从最底层的网络通信原理开始,亲手写一个简单的聊天室,最后用强大的Web框架,把你之前做的待办事项管理系统变成一个真正的Web应用!
13.1 网络编程基础:IP、端口和协议
想象一下,你要给远方的朋友写信。你需要知道两件事:朋友的家庭地址(找到他家的网络)和他家的信箱号码(找到他家具体接收信件的那个端口)。在网络世界里,这就是IP地址和端口号。
IP地址:网络设备的唯一标识,比如 192.168.1.1(局域网)或 127.0.0.1(本地回环地址,指你自己的电脑)。
端口号:一台电脑上可以有多个网络程序在运行,端口就是用来区分这些程序的,范围是0-65535。常见的如Web服务(HTTP)默认用80端口,HTTPS用443。
协议:就是通信的“语言”和“规则”。最重要的有TCP和UDP。TCP像打电话,需要建立连接,确保数据准确送达(如网页浏览);UDP像发短信,只管发,不保证对方一定收到,但速度快(如视频直播)。
13.2 用socket模块实现一个简单的聊天程序
Python内置的socket模块提供了对底层网络接口的访问。我们用TCP协议来模拟一个简单的“一问一答”服务。
服务端(server.py):等待别人来连接的“接听方”
python
import socket# 1. 创建socket对象,指定IPv4地址族和TCP协议server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 2. 绑定IP和端口(''代表本机所有可用IP,比如127.0.0.1)server_socket.bind(('',12345))# 3. 开始监听,最多允许5个连接等待处理server_socket.listen(5)print("服务端已启动,正在监听端口12345...")# 4. 接受一个客户端的连接(这里会阻塞,直到有客户端连接)client_socket, client_addr = server_socket.accept()print(f"接受到来自 {client_addr} 的连接")# 5. 接收客户端发来的数据data = client_socket.recv(1024)# 一次最多接收1024字节print(f"收到消息: {data.decode('utf-8')}")# 6. 发送回复给客户端reply ="消息已收到,你好,客户端!"client_socket.send(reply.encode('utf-8'))# 7. 关闭连接client_socket.close()server_socket.close()客户端(client.py):主动发起连接的“打电话方”
python
import socket# 1. 创建socket对象client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 2. 连接服务端(需要知道服务端的IP和端口)# 如果服务端在另一台电脑,替换'127.0.0.1'为它的IP地址client_socket.connect(('127.0.0.1',12345))# 3. 发送数据message ="你好,服务端!"client_socket.send(message.encode('utf-8'))print(f"发送消息: {message}")# 4. 接收服务端回复data = client_socket.recv(1024)print(f"收到回复: {data.decode('utf-8')}")# 5. 关闭连接client_socket.close()试试看:先运行server.py,再运行client.py,你会看到它们在控制台愉快地“对话”。虽然简单,但这已经是网络通信的雏形了!
13.3 初识HTTP协议与Web框架
用socket直接写一个网站会非常复杂,因为我们需要自己处理HTTP协议(浏览器和服务器沟通的语言)。比如,浏览器发送的请求长这样:
text
GET /index.html HTTP/1.1Host: www.example.comUser-Agent: Mozilla/5.0 ......
我们需要解析这些文本,找出用户想访问哪个页面(比如/index.html),然后返回对应的HTML内容,还要加上特定的响应头。这就是Web框架诞生的原因。
Web框架(如Flask、Django)帮我们处理了所有底层协议和请求解析的脏活累活,让我们能专注于业务逻辑——“当用户访问这个网址时,应该做什么”。
13.4 实战:用Flask将待办系统变为Web应用
Flask是一个轻量级、易上手的Python Web框架。我们来用它改造上一章的待办系统,让待办事项可以通过网页查看和添加。
13.4.1 安装Flask
首先,在命令行中安装Flask:
bash
pip install flask
13.4.2 编写Flask应用
创建一个新文件 todo_web.py,它将结合Flask和SQLAlchemy。
python
# todo_web.pyfrom flask import Flask, request, redirect, url_for, render_template_stringfrom sqlalchemy import create_engine, Column, Integer, String, Booleanfrom sqlalchemy.orm import declarative_base, sessionmakerfrom datetime import datetime# ---------- 1. 数据库部分(直接复用之前ORM的模型)----------engine = create_engine('sqlite:///todos.db')Base = declarative_base()classTodoItem(Base): __tablename__ ='todos'id= Column(Integer, primary_key=True) content = Column(String(200), nullable=False) is_done = Column(Boolean, default=False) created_at = Column(String(20), default=datetime.now().strftime("%Y-%m-%d %H:%M"))Base.metadata.create_all(engine)Session = sessionmaker(bind=engine)# ---------- 2. Flask Web应用部分 ----------# 创建一个Flask应用实例app = Flask(__name__)# 一个非常简单的HTML模板(实际开发会放在单独文件里)HTML_TEMPLATE ='''<!DOCTYPE html><html><head> <title>我的待办事项</title> <style> body { font-family: sans-serif; margin: 40px; } .todo-item { margin: 10px 0; } .done { text-decoration: line-through; color: gray; } </style></head><body> <h1>📝 待办事项清单</h1> <form action="/add" method="post"> <input type="text" name="content" placeholder="输入新事项..." required> <button type="submit">添加</button> </form> <ul> {% for todo in todos %} <li class="todo-item"> <span class="{{ 'done' if todo.is_done else '' }}"> {{ todo.content }} (创建于: {{ todo.created_at }}) </span> <a href="/done/{{ todo.id }}">[完成]</a> <a href="/delete/{{ todo.id }}">[删除]</a> </li> {% else %} <li>🎉 恭喜,没有待办事项了!</li> {% endfor %} </ul></body></html>'''@app.route('/')defindex():"""主页:显示所有待办事项""" session = Session() todos = session.query(TodoItem).all() session.close()# 使用模板渲染数据return render_template_string(HTML_TEMPLATE, todos=todos)@app.route('/add', methods=['POST'])defadd_todo():"""处理添加待办的请求""" content = request.form.get('content')if content: session = Session() new_item = TodoItem(content=content) session.add(new_item) session.commit() session.close()# 重定向回主页return redirect(url_for('index'))@app.route('/done/<int:todo_id>')defmark_done(todo_id):"""标记某个待办为完成""" session = Session() todo = session.query(TodoItem).filter_by(id=todo_id).first()if todo: todo.is_done =True session.commit() session.close()return redirect(url_for('index'))@app.route('/delete/<int:todo_id>')defdelete_todo(todo_id):"""删除某个待办""" session = Session() todo = session.query(TodoItem).filter_by(id=todo_id).first()if todo: session.delete(todo) session.commit() session.close()return redirect(url_for('index'))# ---------- 3. 启动Web应用 ----------if __name__ =='__main__':# debug=True 会在代码修改后自动重启服务器,并显示详细错误 app.run(host='127.0.0.1', port=5000, debug=True)13.4.3 运行你的第一个Web应用
保存代码为 todo_web.py。
在终端中运行:python todo_web.py。
打开浏览器,访问 http://127.0.0.1:5000。
你会看到你的待办事项以网页形式呈现了!你可以通过网页添加、完成、删除事项,所有操作都会实时保存到数据库里。
代码魔法解析:
@app.route('/') 是一个装饰器,它将下面的index函数绑定到了网址根路径/上。当用户访问这个网址时,Flask就会执行index函数。
render_template_string 把我们查询到的todos数据填充到HTML模板中,生成最终的HTML页面。
redirect(url_for('index')) 在处理完添加、删除等操作后,让浏览器重新跳转到主页,刷新页面。
13.5 本章小结
网络基础:理解了IP地址、端口和TCP/UDP协议的角色,并用socket亲手实现了一个简单的C/S通信。
HTTP与Web框架:知道了浏览器和服务器通过HTTP协议沟通,而Web框架(如Flask)能极大简化网站开发。
实战飞跃:成功将上一章的待办事项系统,从一个命令行程序,升级为一个可通过浏览器访问的动态Web应用。这标志着你已经从一个纯脚本开发者,迈入了Web开发的大门!
✨ 重点回顾
网络通信三要素:IP地址(找设备)、端口号(找程序)、协议(怎么聊)。
Socket是基石:socket模块是网络通信的底层接口,了解bind、listen、accept、connect、send、recv的核心流程。
Flask三板斧:
路由 (@app.route):将网址映射到Python函数。
视图函数:处理请求,从数据库取数据,返回响应(如HTML页面)。
模板渲染:将数据动态填充到HTML中,生成最终页面。
Web与数据库结合:将数据库操作封装在视图函数中,实现了数据的持久化展示和操作。
下一章预告:数据分析与可视化入门
现在你的程序不仅能存储数据,还能通过网页展示和交互了!但有时候,面对一大堆数据,我们很难一眼看出规律。下一章,我们将学习如何用Python进行数据分析与可视化,用pandas处理数据,用matplotlib和pyecharts画出漂亮的图表,让数据自己“说话”。准备好了吗?我们将进入一个充满数字和图形的精彩世界!
希望这个续写符合您的预期。这个章节延续了原教程从基础到实战、逐步进阶的风格,并再次改造了经典的“待办事项”项目,能让读者直观感受到知识的累积和应用的强大。