输入输出:print格式化、input交互
一句话概述
输入输出(I/O)是程序与外界沟通的"嘴巴"和"耳朵"——没有 I/O,程序就像一个与世隔绝的孤岛,计算结果自己知道但谁也看不到。Python 的 print() 函数负责输出,不仅是调试利器,还能通过各种格式化技巧把数据美观地展示出来;input() 函数负责接收用户输入,让程序从"死程序"变成可以交互的"活工具"。掌握 print 的高级格式化(f-string、format 规范、sep/end 参数)和 input 的类型转换,是写出专业级 Python 程序的必修课。
💡 核心要点:①print() 的 sep 控制分隔符,end 控制结尾字符(默认换行)②f-string 是最高效直观的格式化方式,支持 :.2f 等格式规范 ③input() 总是返回字符串,需要数值时必须用 int()/float() 转换 ④print() 的 file 参数可将输出写入文件 ⑤在 AI 开发中,print 用于训练日志、模型评估输出,input 用于交互式推理和参数调节
教学与演示
一、print()——程序的"嘴巴"
是什么:print() 是 Python 内置的输出函数,将内容显示到控制台(标准输出)。它可以接受多个参数,用 sep 指定分隔符(默认空格),用 end 指定结尾字符(默认换行符)。print() 能输出几乎所有 Python 对象(数字、字符串、列表、字典等)。
大白话print()就是程序的"说"——你想让程序告诉你什么,就用 print。print("你好")就是程序在说"你好"。多个参数时,print 默认用空格隔开它们。end参数控制"说完之后加什么"——默认加换行(另起一行),你可以改成不加换行(接着后面说)或者打个逗号。
为什么:print() 是每个程序员用得最多的函数,没有之一。调试代码时它是"人肉断点"——在关键位置加 print(variable) 看值对不对;展示结果时它是漂亮输出的工具;训练 AI 模型时它是"心跳监测器"——每隔几步打印一次 loss 和 accuracy,让你知道模型在不在正常学习。
大白话 没有 print,你就不知道程序在干嘛——它像一个蒙眼跑步的人,你只知道他开始跑了和跑完了,中间发生了什么一概不知。AI 训练动辄几小时,没有中间的 print 日志,你会焦虑到怀疑人生:"这模型到底是在学习还是死机了?"
怎么做:
import numpy as np
# ====== 1. print 基本用法 ======
# 输出单个值
print("Hello, Python!") # 输出: Hello, Python!
# 输出多个值(默认用空格分隔)
name = "小明"
age = 18
print("姓名:", name, "年龄:", age) # 姓名: 小明 年龄: 18
# 直接输出表达式计算结果
print("3 + 5 =", 3 + 5) # 3 + 5 = 8
# 输出各种数据类型
print(42) # 整数
print(3.14159) # 浮点数
print(True) # 布尔值
print([1, 2, 3]) # 列表
print({"name": "Alice", "age": 25}) # 字典
# ====== 2. sep 参数——自定义分隔符 ======
print("\n=== sep 参数 ===")
# 默认:用空格分隔
print("苹果", "香蕉", "橘子") # 苹果 香蕉 橘子
# sep='':没有分隔符
print("Hello", "World", sep='') # HelloWorld
# sep=' | ':用竖线分隔
print("苹果", "香蕉", "橘子", sep=' | ') # 苹果 | 香蕉 | 橘子
# sep='\n':用换行分隔(每个参数一行)
print("第一行", "第二行", "第三行", sep='\n')
# 输出:
# 第一行
# 第二行
# 第三行
# 实用场景:输出 CSV 格式数据
print("ID", "姓名", "分数", sep=',') # ID,姓名,分数(CSV 表头)
print("1", "张三", "95", sep=',') # 1,张三,95
# ====== 3. end 参数——控制结尾字符 ======
print("\n=== end 参数 ===")
# 默认:end='\n'(换行)
print("第一行")
print("第二行") # 每个 print 自动换行
# end='':不换行,后续输出紧跟着
print("加载中", end='')
print("...", end='')
print("完成!") # 加载中...完成!
# end=' → ':用箭头连接
print("步骤1", end=' → ')
print("步骤2", end=' → ')
print("步骤3") # 步骤1 → 步骤2 → 步骤3
# 模拟进度条(AI 训练中最常见的 print 用法)
import time
print("\n模拟训练进度:")
for i in range(5):
progress = (i + 1) * 20 # 20%, 40%, 60%, 80%, 100%
# \r 回到行首,end='' 不换行,实现原地刷新
print(f"\r 训练进度: [{'=' * (i+1)}{' ' * (4-i)}] {progress}%", end='')
# 实际开发中用 time.sleep 模拟训练时间
print() # 最后换行
# ====== 4. 输出到文件(file 参数) ======
print("\n=== 输出到文件 ===")
# file 参数可将输出写入文件而非控制台
with open('/tmp/demo_output.txt', 'w') as f:
print("这是第一行", file=f) # 写入文件
print("这是第二行", file=f) # 写入文件
# 验证文件内容
with open('/tmp/demo_output.txt', 'r') as f:
content = f.read()
print(f"文件内容:\n{content}")
# ====== 5. 输出特殊字符 ======
# 转义字符
print("\n=== 转义字符 ===")
print("第一行\n第二行") # \n 换行
print("列1\t列2\t列3") # \t 制表符(对齐列)
print("他说: \"你好\"") # \" 输出引号本身
print("路径: C:\\Users\\Documents") # \\ 输出反斜杠本身
# 原始字符串(r-string):不处理转义
print(r"C:\Users\Documents\new") # \n 不会被解释为换行什么用:在 AI 开发中,print() 的用途多到数不清。训练循环中打印 loss 和 accuracy(print(f"Epoch {epoch}, Loss: {loss:.4f}, Acc: {acc:.2%}")),用 \r 实现原地刷新的进度条;数据探查时打印 DataFrame 的前几行和统计摘要;调试时插入 print(type(x), x.shape) 确认变量类型和维度;模型推理时打印预测结果和置信度。sep 和 end 参数在输出 CSV、格式化表格时特别有用。
二、f-string 格式化——Python 最强格式化工具
是什么:f-string(格式化字符串字面量)是 Python 3.6 引入的字符串格式化语法,以 f 前缀开头,花括号 {} 内可以放任何 Python 表达式。它比老式的 % 格式化和 .format() 方法更快、更直观。f-string 支持格式规范迷你语言——你可以在花括号内用 : 后面指定宽度、精度、对齐、填充等。
大白话 f-string 就是"模板填空"——你先写好一个句子模板(比如"{} 今年 {} 岁"),然后 f-string 帮你把花括号里的变量值填进去。而且它不只是"填进去"——你还可以指定怎么填:保留几位小数(:.2f)、加千位分隔符(,.0f)、左对齐右对齐(<、>)、百分比显示(:.1%)。
为什么:格式化输出是程序"专业化"的标志。直接 print(x) 输出 3.141592653589793 很难看,用 f-string 输出 π ≈ 3.14 就干净多了。在 AI 项目中,美观的日志输出不仅让你自己调试更方便,也让合作者更容易理解你的实验结果。
大白话 想象你是一个厨师,做了一道菜。你可以直接端着锅上桌(print(x)),也可以用漂亮的盘子摆盘(f-string 格式化)。功能上没区别——都能吃(都能输出),但摆过盘的菜看起来像回事,别人也更愿意尝。
怎么做:
import numpy as np
import math
# ====== 1. f-string 基本用法 ======
print("=== f-string 基本用法 ===")
name = "小明"
age = 18
score = 95.5
# 基本插值
print(f"{name}今年{age}岁,考了{score}分") # 小明今年18岁,考了95.5分
# 花括号内可以放任意表达式
print(f"10 + 20 = {10 + 20}") # 10 + 20 = 30
print(f"年龄翻倍:{age * 2}") # 年龄翻倍:36
# 调用函数
print(f"名字大写:{name.upper()}") # 名字大写:小明
# 中文的 upper() 不变,换英文试试
en_name = "alice"
print(f"英文名大写:{en_name.upper()}") # 英文名大写:ALICE
# ====== 2. 数字格式化(最常用!) ======
print("\n=== 数字格式化 ===")
pi = 3.141592653589793
price = 1234567.89
ratio = 0.8523
big_num = 9876543210
# 保留小数位数
print(f"π ≈ {pi:.2f}") # π ≈ 3.14 — 保留2位小数
print(f"π ≈ {pi:.4f}") # π ≈ 3.1416 — 保留4位小数(四舍五入)
# 千位分隔符
print(f"价格: {price:,.2f}") # 价格: 1,234,567.89 — 逗号分隔
# 百分比
print(f"准确率: {ratio:.1%}") # 准确率: 85.2% — 自动×100加%号
print(f"准确率: {ratio:.2%}") # 准确率: 85.23%
# 科学计数法
print(f"大数科学计数: {big_num:.2e}") # 大数科学计数: 9.88e+09
# 固定总宽度(不足补空格)
print(f"序号: {1:5d}") # 序号: 1 — 总宽度5,右对齐
print(f"序号: {2:5d}") # 序号: 2
print(f"序号: {100:5d}") # 序号: 100
# 左对齐
print(f"左对齐: {name:<10} world") # 左对齐: 小明 world
# 右对齐(默认数字右对齐)
print(f"右对齐: {42:>10}") # 右对齐: 42
# 居中对齐
print(f"居中: {name:^10}!") # 居中: 小明 !
# 指定填充字符
print(f"填零: {42:0>5}") # 填零: 00042 — 右侧>用0填充左侧
print(f"填星: {name:*^10}") # 填星: ****小明****
# ====== 3. 日期时间格式化 ======
from datetime import datetime
now = datetime.now()
print(f"\n当前时间: {now:%Y-%m-%d %H:%M:%S}") # 当前时间: 2025-01-15 14:30:00
# ====== 4. AI 训练日志格式化实例 ======
print("\n=== AI 训练日志格式化 ===")
# 模拟训练过程中的日志输出
epoch = 5
total_epochs = 100
train_loss = 0.23456
val_loss = 0.34567
accuracy = 0.8912
learning_rate = 0.0015
# 格式化的训练日志(专业美观)
print("=" * 50)
print(f"{'Epoch':>5} | {'Train Loss':>10} | {'Val Loss':>10} | {'Accuracy':>9} | {'LR':>8}")
print("-" * 50)
print(f"{epoch:>5}/{total_epochs:<5} | {train_loss:>10.4f} | {val_loss:>10.4f} | {accuracy:>8.2%} | {learning_rate:>8.0e}")
print("=" * 50)
# 输出效果:
# ==================================================
# Epoch | Train Loss | Val Loss | Accuracy | LR
# --------------------------------------------------
# 5/100 | 0.2346 | 0.3457 | 89.12% | 1.5e-03
# ==================================================
# ====== 5. f-string 中需要输出花括号本身 ======
# 双花括号转义
print(f"\n集合定义: x ∈ {{1, 2, 3}}") # 集合定义: x ∈ {1, 2, 3}
# ====== 6. 多行 f-string ======
title = "Python基础语法"
section = "输入输出"
author = "AIQZ.CC"
summary = f"""
=== 课程信息 ===
课程: {title}
章节: {section}
来源: {author}
===============
"""
print(summary)什么用:f-string 是 AI 开发中最常用的格式化方式。训练日志的格式化输出(如上例所示)是每个 AI 工程师的日常;模型评估报告的生成(准确率、召回率、F1 分数等都用百分比格式);超参数的可视化展示;TensorBoard 之外的"穷人版"训练监控全靠它。f-string 的 :.4f 格式在打印 loss 值时特别有用——保留 4 位小数能让你看清 loss 在 0.0001 级别的变化。
三、input()——程序的"耳朵"
是什么:input() 函数让程序能接收用户在终端中输入的文本。执行到 input() 时,程序会暂停等待用户输入,直到用户按下回车键。input() 总是返回一个字符串,如果需要数字,必须用 int() 或 float() 转换。可以传入一个提示字符串作为参数,显示在用户输入之前。
大白话input()就是程序的"听"——你对着程序说(打字),程序通过input()接收。它有个特点:不管用户输入什么(数字、字母、标点),input()返回的都是字符串。如果你期待用户输入一个数字,必须自己用int()或float()转换。就像电话那头的人什么都能说,你得自己分辨他说的是数字还是文字。
为什么:input() 让程序从"孤岛"变成"对话伙伴"。没有输入的程序只能处理写死的数据,有了输入就能处理用户提供的数据。在 AI 中,交互式推理就靠 input()——用户输入一张图片路径或一段文本,模型给出预测结果。
大白话 没有input(),你的程序就像一个只会背稿子的机器人——内容固定,回答也固定。有了input(),程序就能根据不同人的不同问题给出不同回答——这才是真正的"程序与人交互"。
怎么做:
import numpy as np
# ====== 1. input() 基本用法 ======
# 提示:由于代码在网页中运行,input() 会使用预设值
# 在实际终端中,程序会暂停等待用户输入
# 基本输入
# user_name = input("请输入你的名字: ")
# print(f"你好, {user_name}!")
# 对于本演示,我们模拟输入
user_name = "演示用户"
print(f"模拟输入 - 名字: {user_name}")
print(f"你好, {user_name}!")
# ====== 2. input() 返回的是字符串! ======
print("\n=== 输入类型转换 ===")
# age_str = input("请输入你的年龄: ")
age_str = "25" # 模拟用户输入
print(f"模拟输入 - 年龄: {age_str}")
print(f"input 返回的类型: {type(age_str).__name__}") # str
# 转换为整数
age = int(age_str) # 把字符串 "25" 转为整数 25
print(f"年龄 + 5 = {age + 5}") # 30 — 现在是整数运算而非字符串拼接
# 如果用户输入的不是数字呢?
# bad_input = "abc"; int(bad_input) # ❌ ValueError!
# 所以要做异常处理(后续章节会讲到)
# ====== 3. 安全的数字输入处理 ======
print("\n=== 安全的数字输入 ===")
def safe_input_number(prompt):
"""安全地获取用户输入的数字"""
while True:
# 在实际终端中,这里会等待用户输入
# 这里用模拟值演示逻辑
user_input = "3.14" # 模拟用户输入
print(f"模拟输入: {user_input}")
try:
# 尝试转换为浮点数
number = float(user_input)
# 如果是整数(如 3.0),转为 int 更干净
if number == int(number):
return int(number)
return number
except ValueError:
print(f"无效输入 '{user_input}',请输入一个数字")
result = safe_input_number("请输入一个数字: ")
print(f"转换后的数字: {result}, 类型: {type(result).__name__}")
# ====== 4. 读取多个值(用 split 分割) ======
print("\n=== 读取多个值 ===")
# 用户输入 "85 92 78" — 三个分数用空格分隔
raw_input = "85 92 78" # 模拟输入
print(f"模拟输入: {raw_input}")
# 用 split() 分割,再用 map 转换
parts = raw_input.split() # ['85', '92', '78']
scores = [int(x) for x in parts] # [85, 92, 78]
print(f"分数列表: {scores}")
print(f"最高分: {max(scores)}") # 92
print(f"平均分: {np.mean(scores):.1f}") # 89.0
# ====== 5. 交互式菜单(AI 推理中的常见模式) ======
print("\n=== 交互式菜单 ===")
def show_menu():
"""显示交互菜单"""
print("\n" + "=" * 30)
print(" AI 模型推理工具")
print("=" * 30)
print(" 1. 图片分类")
print(" 2. 文本情感分析")
print(" 3. 目标检测")
print(" 0. 退出")
print("-" * 30)
# 在实际终端中: choice = input("请选择功能 (0-3): ")
choice = "2" # 模拟用户选择
print(f"模拟选择: {choice}")
return choice
choice = show_menu()
# 根据用户选择执行不同的推理任务
if choice == "1":
print("正在加载图片分类模型...")
# image_path = input("请输入图片路径: ")
# result = model.predict(image_path)
print("预测结果: 🐱 猫 (置信度: 95.3%)")
elif choice == "2":
print("正在加载文本情感分析模型...")
# text = input("请输入文本: ")
text = "这部电影太棒了!" # 模拟输入
print(f"输入文本: {text}")
print("情感分析结果: 正面 😊 (置信度: 87.2%)")
elif choice == "3":
print("目标检测功能开发中...")
elif choice == "0":
print("退出程序")
else:
print("无效选项,请输入 0-3 之间的数字")
# ====== 6. 批量数据处理中的输入输出 ======
print("\n=== 模拟批量数据处理 ===")
# 场景:用户输入一串数字,程序计算统计信息
raw_data = "23, 45, 12, 67, 34, 89, 56, 78, 90, 11"
print(f"输入数据: {raw_data}")
# 解析数据
data = np.array([float(x.strip()) for x in raw_data.split(',')])
print(f"样本数: {len(data)}")
print(f"均值: {np.mean(data):.2f}")
print(f"标准差: {np.std(data):.2f}")
print(f"最大值: {np.max(data)}")
print(f"最小值: {np.min(data)}")
print(f"中位数: {np.median(data):.1f}")什么用:在 AI 中,input() 的主要应用包括:①交互式推理——用户输入文本/图片路径,模型实时输出预测;②训练参数调节——在训练开始前让用户输入 batch_size、epochs 等超参数;③数据标注工具——显示一个样本,让标注员输入标签;④命令行工具——用 input() 构建简单的 CLI 菜单。不过在生产环境中,input() 更多被 argparse(命令行参数)或 Web API 替代——前者更适合脚本自动化,后者更适合服务化部署。
四、综合应用——打造一个 AI 数据探查工具
是什么:本节我们综合运用 print() 的格式化能力和 input() 的交互能力,用 NumPy 打造一个小型的数据探查工具。这个工具能接收用户输入的数据,进行统计分析,并以美观的表格形式输出结果。
大白话 把学到的 print 格式化和 input 交互串起来,做一个"迷你 AI 助手"——输入一串数字,它能告诉你这组数据的"相貌"(均值、标准差、最大值、最小值等)。这才是学以致用!
为什么:实际开发中,print() 和 input() 从来不是孤立的——它们搭配使用才能构成完整的用户交互体验。这个小示例模拟了 AI 数据预处理阶段最常见的操作——读取数据 → 统计分析 → 格式化输出报告。
怎么做:
import numpy as np
# ====== 综合示例:AI 数据探查工具 ======
print("=" * 60)
print(" 📊 AI 数据探查工具 v1.0")
print("=" * 60)
# 1. 接收用户输入的数据(模拟)
print("\n请输入一组数字,用逗号分隔:")
raw_data = "85, 92, 78, 95, 60, 88, 73, 91, 84, 79"
print(f"> {raw_data}")
# 2. 解析数据
try:
data = np.array([float(x.strip()) for x in raw_data.split(',')])
print(f"\n✅ 成功读取 {len(data)} 条数据")
except ValueError:
print("\n❌ 数据格式错误,请确认输入的是数字")
data = None
if data is not None:
# 3. 计算统计指标
data_min = np.min(data) # 最小值
data_max = np.max(data) # 最大值
data_mean = np.mean(data) # 均值
data_median = np.median(data) # 中位数
data_std = np.std(data) # 标准差
data_var = np.var(data) # 方差
data_sum = np.sum(data) # 总和
# 4. 格式化输出统计报告
print("\n" + "=" * 60)
print(f"{'数据统计报告':^50}")
print("=" * 60)
print(f" {'样本数量:':20s} {len(data):>10d}")
print(f" {'总和:':20s} {data_sum:>10.1f}")
print(f" {'平均值 (Mean):':20s} {data_mean:>10.2f}")
print(f" {'中位数 (Median):':20s} {data_median:>10.2f}")
print(f" {'标准差 (Std):':20s} {data_std:>10.2f}")
print(f" {'方差 (Var):':20s} {data_var:>10.2f}")
print(f" {'最小值 (Min):':20s} {data_min:>10.2f}")
print(f" {'最大值 (Max):':20s} {data_max:>10.2f}")
print(f" {'极差 (Range):':20s} {data_max - data_min:>10.2f}")
print(f" {'变异系数 (CV):':20s} {data_std/data_mean:>10.2%}")
print("-" * 60)
# 5. 数据分布分析
# 分段统计
print(f"\n{'数据分布分析':^50}")
print("-" * 60)
bins = [60, 70, 80, 90, 100]
labels = ['60-69 (及格)', '70-79 (中等)', '80-89 (良好)', '90-100 (优秀)']
for i in range(len(labels)):
count = int(np.sum((data >= bins[i]) & (data < bins[i+1]) if i < len(labels)-1
else (data >= bins[i]) & (data <= bins[i+1])))
bar = '█' * count # 简易柱状图
percentage = count / len(data)
print(f" {labels[i]:15s}: {count}人 {percentage:>6.1%} {bar}")
# 6. 异常值检测(简单版:Z-score > 2)
print(f"\n{'异常值检测 (|Z-score| > 2)':^50}")
print("-" * 60)
z_scores = (data - data_mean) / data_std # 标准化
outliers_found = False
for i, (val, z) in enumerate(zip(data, z_scores)):
if abs(z) > 2:
print(f" ⚠️ 第{i+1}个值 {val:.1f} (Z-score = {z:+.2f}) 可能为异常值")
outliers_found = True
if not outliers_found:
print(" ✅ 未发现明显异常值")
print("\n" + "=" * 60)
print(f"{'报告生成完毕':^50}")
print("=" * 60)什么用:这个数据探查工具的模式在 AI 开发中无处不在。每个数据科学家都会在拿到新数据集后先"看一眼"——均值、方差、分布、缺失值比例。虽然真实项目会用 Pandas 的 df.describe() 一行搞定,但理解底层原理能让你在 Pandas 不可用时(比如数据极其巨大需要用迭代器)自己实现分析逻辑。同时这个案例也展示了 print 格式化在实际项目中的完整用法。
概念关系图谱
| 概念 | 核心含义 | 与AI的关系 | 关联概念 |
|---|---|---|---|
| print() | 输出函数,将内容显示到控制台 | 训练日志、模型评估、调试 | sys.stdout, 文件输出 |
| sep参数 | print的多值分隔符 | CSV输出、格式化分隔 | join() |
| end参数 | print的结尾字符 | 进度条、不换行输出 | \r 回车符 |
| f-string | 格式化字符串字面量 | 日志格式化、报告生成 | format(), %格式化 |
| 格式规范 | :.2f 等迷你语言 | 数值美观输出 | 宽度、精度、对齐 |
| input() | 交互式输入函数 | 交互推理、参数输入 | sys.stdin, argparse |
| 类型转换 | str→int/float | 安全读取数值输入 | try/except |
| 转义字符 | \n \t \ 等特殊字符 | 表格对齐、换行 | 原始字符串 |
| 标准输出 | sys.stdout | 日志重定向 | 文件流 |
| 交互式菜单 | 用户选择驱动的程序流 | CLI工具、标注工具 | 命令行参数 |
重点答疑
Q1: f-string 和 .format() 和 %格式化 应该用哪个?
三者的功能和效率从低到高是:% < .format() < f-string。f-string 最快(在编译时解析,不需要运行时查找变量),最直观(变量就在花括号里),功能最全(支持所有格式规范)。% 格式化是老式写法,你会在旧代码中看到,但新代码不要再用。.format() 在需要复用模板(如同一模板对不同数据多次格式化)时仍有优势。结论:新代码一律用 f-string,维护旧代码时遵循原项目的风格。
Q2: input() 返回的是字符串,为什么 input() + int() 不是自动完成的?
这是 Python 的"显式优于隐式"设计哲学。input() 只负责"读取用户输入"这一件事(单一职责原则),类型转换是另一件事。如果 input() 自动判断类型,当用户输入 "123" 时你怎么知道他要的是数字 123 还是字符串 "123"?这种"猜测"会引入不确定性。所以 Python 让你显式转换——你心里清楚你要的是什么,你手动告诉 Python。
Q3: print 的 end='' 和 \r 有什么区别?
end 控制 print 输出完之后加什么字符,默认加 \n(换行)。\r 是"回车符"——光标回到当前行的最开头,但不下移一行。组合使用 end='' 和 \r:print(f"\r进度: {i}%", end=''),效果是每次输出都在同一行覆盖上一次的输出(因为 \r 把光标拉回行首),实现"原地刷新"效果。这在不支持复杂 UI 库的终端中模拟进度条非常实用。
Q4: 如果用户乱输入(比如要数字却输入了字母),怎么处理?
这是 input() 最常见的问题,答案是 try/except。把 int(input()) 或 float(input()) 放在 try 块中,捕获 ValueError 异常。更完整的方案是用一个 while 循环,只要转换失败就提示用户重新输入,直到合法为止。这在 AI 工具开发中很常见——你必须假设用户可能输入任何东西(所谓"防御性编程")。
Q5: print 可以同时输出到终端和文件吗?
可以,但需要一点额外工作。最简单的方式是用 tee 命令在终端层面处理。Python 层面,你可以自定义一个类,重写 write 方法同时写入两个流,然后 sys.stdout = MyTeeClass(sys.stdout, file_obj)。或者更简单的:定义一个辅助函数 def tee_print(*args, file=None, **kwargs):,内部同时调用 print(*args, **kwargs) 和 print(*args, file=file, **kwargs)。这在需要同时看日志和保存日志的训练脚本中很常用。
章节单词汇总
| 英文 | 音标 | 术语/释义 |
|---|---|---|
| /prɪnt/ | 打印/输出,将内容显示到控制台 | |
| input | /ˈɪnpʊt/ | 输入,从用户获取数据 |
| format | /ˈfɔːrmæt/ | 格式化,按模板装饰输出内容 |
| f-string | /ef strɪŋ/ | 格式化字符串字面量 |
| separator | /ˈsepəreɪtər/ | 分隔符,sep参数 |
| end parameter | /end pəˈræmɪtər/ | 结尾参数,end参数 |
| standard output | /ˈstændərd ˈaʊtpʊt/ | 标准输出,默认的输出流 |
| carriage return | /ˈkærɪdʒ rɪˈtɜːrn/ | 回车符 \r,光标回到行首 |
| escape character | /ɪˈskeɪp ˈkærɪktər/ | 转义字符,如 \n \t \ |
| type conversion | /taɪp kənˈvɜːrʃn/ | 类型转换,如 str→int |
| stdout | /ˈstændərd aʊt/ | 标准输出流的缩写 |
| raw string | /rɔː strɪŋ/ | 原始字符串,不处理转义 |
面试练习
Q1 [单选] 以下代码的输出是什么?print("Hello", "World", sep="-", end="!")
- A.
Hello World! - B.
Hello-World! - C.
Hello-World(无感叹号) - D.
Hello-World!然后换行
解答:sep="-"用横杠分隔两个参数得到 "Hello-World",end="!"用感叹号代替换行。但end之后不换行——不过题目问的就是输出内容,"Hello-World!" 正确。B 可选正确,但严格来说这个 print 后不加换行,下一个 print 会紧跟在同一行。
Q2 [单选] f-string 中 {3.14159:.2f} 的结果是?
- A.
3.14 - B.
3.14 - C.
3.14159 - D.
3.1
解答:.2f表示保留 2 位小数,四舍五入。3.14159 保留 2 位是 3.14。.2f而不是.2d——f是 float 格式。
Q3 [单选] input() 函数返回的数据类型是什么?
- A. 与用户输入一致(输入数字就是 int,输入文字就是 str)
- B. 永远是 str(字符串)
- C. 永远是 bytes(字节)
- D. 取决于操作系统
解答:input()永远返回字符串,无论用户输入的是什么。这是 Python 的设计选择——input()只负责"读取",类型推断由用户显式控制。
Q4 [多选] 以下哪些是 print 函数的合法参数?
- A.
sep - B.
end - C.
file - D.
encoding
解答:A、B、C 都是 print 的参数。sep控制分隔符,end控制结尾字符,file控制输出目标。D 错误——print 的 file 参数接受的是一个文件对象(已经打开并确定了编码),print 本身没有 encoding 参数。
Q5 [单选] 以下哪个是安全地将 input 输入转为整数的方式?
- A.
num = int(input()) - B.
num = eval(input()) - C. 用 try/except 包裹
int(input())捕获 ValueError - D.
num = input().to_int()
解答:A 不安全——用户输入非数字会程序崩溃。B 极其危险——eval() 会执行任意 Python 代码,存在严重安全漏洞。C 是正确的安全做法。D 语法不存在。
Q6 [单选] print("第一行", end=" → "); print("第二行") 的输出是?
- A. 第一行 → 第二行(分两行)
- B. 第一行 → 第二行(在同一行)
- C. 第一行第二行(没有箭头)
- D. 语法错误
解答:第一个 print 以 → 结尾而不换行,第二个 print 紧跟在后面输出"第二行"然后换行。最终一行输出:"第一行 → 第二行"。分号可以在一行中分隔多条语句。
Q7 [多选] 关于 f-string,以下哪些是正确的?
- A.
f"{value:.1%}"会以百分比格式输出(如0.85→85.0%) - B.
f"{name:*^10}"会用星号填充使内容居中 - C. f-string 的花括号内可以放任意 Python 表达式
- D. f-string 的输出会自动去掉首尾空白
解答:A、B、C 都正确。D 错误——f-string 不会自动去空白,去空白是 .strip() 方法的事。
Q8 [单选] 如果不使用 end='',以下代码第 3 行会显示什么?
for i in range(1, 4):
print(i)- A.
123 - B. 分三行显示 1、2、3
- C.
1 2 3 - D.
(1, 2, 3)
解答:每个print(i)默认以换行结尾,所以三个数字各占一行。如果想在一行用空格分隔,需要用print(i, end=' ')。
Q9 [多选] 以下哪些是 Python 中输出训练日志的合理做法?
- A. 使用 f-string 格式化 loss 和 accuracy 的数值
- B. 用
\r和end=''实现原地刷新进度条 - C. 将日志同时输出到控制台和文件
- D. 用
print = lambda *x: None禁用所有输出
解答:A、B、C 都是合理的做法。D 虽然技术上可行(把 print 替换为空函数),但完全禁用输出会丢失所有调试信息,不推荐。
Q10 [单选] print(r"C:\new\tab") 的输出是什么?
- A.
C:+ 换行 +ew ab(\n 和 \t 被转义) - B.
C:\new\tab(原文照印) - C. 报错,因为
\n和\t是非法转义 - D.
C:\new ab(\t 变空格)
解答:r"..."是原始字符串,所有转义字符都不生效,反斜杠就是反斜杠本身。所以输出原文C:\new\tab。