2.1.4 输入与输出

这一节让程序开始和用户互动。你会学会用 input 接收信息、用 print 展示结果,并掌握 f-string 格式化输出,为后面的命令行工具、API 调试和结果展示打基础。
- 掌握
print()的各种用法和格式化输出 - 学会用
input()获取用户输入 - 理解 f-string 格式化的高级用法
- 能编写简单的交互式程序
新人学 Python 时,先抓住这条线就够了:程序拿到输入,做一点处理,再输出结果。后面的 CLI、API、RAG 和 Agent 本质上也都在重复这条线。
先看一个小程序
Section titled “先看一个小程序”service = input("请输入服务名称: ")latency_ms = int(input("请输入延迟(ms): "))
print(f"服务: {service}")print(f"延迟秒数: {latency_ms / 1000:.2f}")print(f"10 ms 后的告警阈值: {latency_ms + 10} ms")运行效果:
| 字段 | 值 |
|---|---|
| 服务输入 | 登录 API |
| 延迟输入 | 185 ms |
| 打印秒数 | 0.18 |
| 打印阈值 | 195 ms |
这就是最基本的输入输出——input() 负责接收数据,print() 负责展示结果。
print() 详解
Section titled “print() 详解”print() 是你最常用的函数,没有之一。
print() 基本用法
Section titled “print() 基本用法”# 打印字符串print("Hello, World!")
# 打印数字print(42)print(3.14)
# 打印变量name = "Python"print(name)
# 打印表达式的结果print(1 + 2 + 3) # 6# 用逗号分隔,print 会自动用空格连接print("服务:", "登录 API", "延迟:", 185, "ms")# 输出: 服务: 登录 API 延迟: 185 ms
# 自定义分隔符print("2026", "01", "15", sep="-")# 输出: 2026-01-15
print("lint", "test", "deploy", sep=" | ")# 输出: lint | test | deploy# 默认每个 print 之后会换行print("第一行")print("第二行")# 输出:# 第一行# 第二行
# 用 end 参数改变结尾字符print("Hello", end=" ")print("World")# 输出: Hello World(在同一行)
# 用 end 实现简单的进度显示print("加载中", end="")print(".", end="")print(".", end="")print(".", end="")print(" 完成!")# 输出: 加载中... 完成!打印特殊字符
Section titled “打印特殊字符”# 换行符 \nprint("第一行\n第二行\n第三行")# 输出:# 第一行# 第二行# 第三行
# 制表符 \t(用来对齐)print("任务\t负责人\t状态")print("登录 API\tMina\t完成")print("仪表盘 UI\tKai\t进行中")# 输出:# 任务 负责人 状态# 登录 API Mina 完成# 仪表盘 UI Kai 进行中
# 反斜杠本身 \\print("文件路径: C:\\Users\\Desktop")
# 原始字符串(不处理转义)print(r"文件路径: C:\Users\Desktop") # r 前缀表示原始字符串f-string 格式化(重点)
Section titled “f-string 格式化(重点)”f-string 是 Python 3.6 引入的字符串格式化方式,也是目前最推荐的方式。
f-string 基本用法
Section titled “f-string 基本用法”service = "登录 API"owner = "Mina"latency_ms = 92.567
# 在字符串前加 f,花括号里放变量名print(f"{service} 由 {owner} 负责")# 输出: 登录 API 由 Mina 负责
# 花括号里可以放任何表达式print(f"下一次重试编号是 {2 + 1}")print(f"服务名称有 {len(service)} 个字符")print(f"是否低于 100 ms 目标?{'是' if latency_ms < 100 else '否'}")这是 f-string 最强大的功能之一:
# 控制小数位数pi = 3.141592653589793print(f"π = {pi:.2f}") # 3.14(保留 2 位小数)print(f"π = {pi:.4f}") # 3.1416(保留 4 位小数)
# 百分比accuracy = 0.8734print(f"准确率: {accuracy:.1%}") # 87.3%print(f"准确率: {accuracy:.2%}") # 87.34%
# 千分位分隔population = 1400000000print(f"人口: {population:,}") # 1,400,000,000print(f"人口: {population:_}") # 1_400_000_000
# 科学计数法speed_of_light = 299792458print(f"光速: {speed_of_light:.2e} m/s") # 3.00e+08 m/s
# 整数补零for i in range(1, 4): print(f"第 {i:03d} 集") # 第 001 集、第 002 集、第 003 集# 左对齐、右对齐、居中name = "Python"print(f"|{name:<20}|") # |Python | 左对齐print(f"|{name:>20}|") # | Python| 右对齐print(f"|{name:^20}|") # | Python | 居中
# 用指定字符填充print(f"|{name:*<20}|") # |Python**************|print(f"|{name:*>20}|") # |**************Python|print(f"|{name:*^20}|") # |*******Python*******|
# 实际应用:打印一个简单的表格print(f"{'服务':<16}{'延迟':>10}")print("-" * 20)print(f"{'登录 API':<16}{95:>10}")print(f"{'搜索 API':<16}{187:>10}")print(f"{'Worker':<16}{42:>10}")输出:
服务 延迟--------------------登录 API 95搜索 API 187Worker 42格式化速查表
Section titled “格式化速查表”| 格式 | 含义 | 示例 | 结果 |
|---|---|---|---|
:.2f | 保留 2 位小数 | f"{3.14159:.2f}" | 3.14 |
:.1% | 百分比(1 位小数) | f"{0.873:.1%}" | 87.3% |
:, | 千分位分隔 | f"{1000000:,}" | 1,000,000 |
:.2e | 科学计数法 | f"{12345:.2e}" | 1.23e+04 |
:03d | 补零到 3 位 | f"{5:03d}" | 005 |
:<10 | 左对齐,宽度 10 | f"{'hi':<10}" | hi________ |
:>10 | 右对齐,宽度 10 | f"{'hi':>10}" | ________hi |
:^10 | 居中,宽度 10 | f"{'hi':^10}" | ____hi____ |
input() 获取用户输入
Section titled “input() 获取用户输入”input() 会暂停程序,等待用户输入,然后返回用户输入的字符串。
input() 基本用法
Section titled “input() 基本用法”# input() 返回的始终是字符串!service = input("请输入服务名称: ")print(f"正在检查 {service}!")print(type(service)) # <class 'str'>重要:input() 返回的是字符串
Section titled “重要:input() 返回的是字符串”# 常见陷阱latency = input("请输入延迟(ms): ") # 用户输入 185print(type(latency)) # <class 'str'>,不是 int!
# 如果直接做数学运算会出问题# print(latency + 10) # 报错!字符串不能和数字相加
# 正确做法:先转换类型latency = int(input("请输入延迟(ms): ")) # 输入的同时转成整数print(f"告警阈值: {latency + 10} ms")
# 如果需要浮点数timeout = float(input("请输入超时时间(秒): "))print(f"超时时间是 {timeout} 秒")处理非法输入
Section titled “处理非法输入”用户可能输入你预期之外的内容:
# 用户输入了 "abc" 而不是数字# latency_ms = int(input("请输入延迟毫秒数: ")) # 会报 ValueError!
# 安全的做法(后面学了异常处理会更优雅)user_input = input("请输入一个数字: ")if user_input.isdigit(): number = int(user_input) print(f"你输入的数字是: {number}")else: print("这不是一个有效的数字!")案例 1:简易计算器
Section titled “案例 1:简易计算器”print("=== 简易计算器 ===")num1 = float(input("请输入第一个数: "))num2 = float(input("请输入第二个数: "))
print(f"\n计算结果:")print(f"{num1} + {num2} = {num1 + num2}")print(f"{num1} - {num2} = {num1 - num2}")print(f"{num1} × {num2} = {num1 * num2}")if num2 != 0: print(f"{num1} ÷ {num2} = {num1 / num2:.2f}")else: print("除数不能为 0!")案例 2:AI 训练报告生成器
Section titled “案例 2:AI 训练报告生成器”# 模拟训练结果数据model_name = "ResNet-50"total_epochs = 100train_accuracy = 0.9534val_accuracy = 0.9187train_loss = 0.1245val_loss = 0.2891training_hours = 2.5
# 生成格式化的报告print("=" * 40)print(f"{'模型训练报告':^40}")print("=" * 40)print(f"模型名称: {model_name}")print(f"训练轮数: {total_epochs}")print(f"训练准确率: {train_accuracy:.2%}")print(f"验证准确率: {val_accuracy:.2%}")print(f"训练损失: {train_loss:.4f}")print(f"验证损失: {val_loss:.4f}")print(f"训练时长: {training_hours:.1f} 小时")print("-" * 40)
# 判断模型状态gap = train_accuracy - val_accuracyif gap > 0.05: print(f"⚠️ 过拟合风险: 训练/验证差距 {gap:.2%}")else: print(f"✅ 模型状态良好: 训练/验证差距 {gap:.2%}")print("=" * 40)输出摘要:
| 字段 | 值 |
|---|---|
| 模型 | ResNet-50 |
| 训练轮数 | 100 |
| 准确率 | 训练 95.34%,验证 91.87% |
| 损失 | 训练 0.1245,验证 0.2891 |
| 训练时长 | 2.5 小时 |
| 告警 | 过拟合风险:差距 3.47% |
练习 1:项目状态卡
Section titled “练习 1:项目状态卡”写一个程序,接收功能名、负责人、已完成任务数和总任务数,然后生成格式化的项目状态卡:
feature = input("功能名称: ")owner = input("负责人: ")completed_tasks = int(input("已完成任务数: "))total_tasks = int(input("总任务数: "))progress = completed_tasks / total_tasks
# 在下方生成项目状态卡print("=" * 34)print(f"功能: {feature}")print(f"负责人: {owner}")print(f"进度: {progress:.1%}")print(f"剩余任务: {total_tasks - completed_tasks}")print("=" * 34)练习 2:项目估算表
Section titled “练习 2:项目估算表”# 输入任务信息task1 = "API 接口"hours1 = 5.0rate1 = 40
task2 = "UI 打磨"hours2 = 3.5rate2 = 40
# 打印项目估算表,要求:# 1. 任务名左对齐,数字右对齐# 2. 显示每项成本# 3. 最后显示总计# 提示:使用 f-string 对齐功能subtotal1 = hours1 * rate1subtotal2 = hours2 * rate2total = subtotal1 + subtotal2
print("=" * 46)print(f"{'任务':<18}{'小时':>8}{'费率':>6}{'成本':>12}")print("-" * 46)print(f"{task1:<18}{hours1:>8.1f}{rate1:>6}{subtotal1:>12.2f}")print(f"{task2:<18}{hours2:>8.1f}{rate2:>6}{subtotal2:>12.2f}")print("-" * 46)print(f"{'总计':<32}{total:>14.2f}")练习 3:延迟单位转换器
Section titled “练习 3:延迟单位转换器”写一个程序,让用户输入毫秒延迟,然后输出对应的秒数和分钟数:
latency_ms = float(input("请输入延迟(ms): "))# 1000 毫秒 = 1 秒# 60 秒 = 1 分钟seconds = latency_ms / 1000minutes = seconds / 60print(f"{latency_ms:.2f} ms = {seconds:.2f} 秒")print(f"{latency_ms:.2f} ms = {minutes:.2f} 分钟")参考实现与讲解
input()返回字符串。已完成/总任务数要用int()转换,延迟要用float()转换后才能做数学运算。- 状态卡输出应该有上下分隔线,并且内容来自用户实际输入。
- 项目估算表应对齐列,并对给定数据算出成本
200.00、140.00,总计340.00。 - 当
latency_ms = 2500时,秒数是2.50,分钟数约为0.04。 - 转换失败时,检查是否输入了空值、非数字、全角数字,或把单位一起输入到了数字栏。
学完这一页,至少保留这张证据卡:
- 概念
- 变量、类型、运算符、输入/输出、分支、循环、结构、函数或模块
- 代码
- 用于说明该概念的最小可运行 Python 代码片段
- 输出
- 打印值、类型、分支结果、循环 trace,或返回值
- 失败检查
- 类型不匹配、缩进错误、越界、可变数据或导入路径问题
- 期望产出
- 代码和打印结果,证明概念可行
| 函数/语法 | 用途 | 关键点 |
|---|---|---|
print() | 输出信息 | sep 改分隔符,end 改结尾 |
input() | 获取用户输入 | 返回值始终是字符串 |
f"..." | 格式化字符串 | {变量:格式} 控制显示方式 |
int() / float() | 类型转换 | input() 后通常需要转换 |