news 2026/9/8 4:35:22

Python输入输出全解析:从input()到文件读写,避开常见坑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python输入输出全解析:从input()到文件读写,避开常见坑

很多刚接触Python的朋友,一上来就盯着变量、循环、函数这些东西猛学,结果真到自己写点小工具的时候,反而卡在“怎么把数据弄进去、怎么把结果拿出来”这个最基础的环节上。这次借着“课件1-3:Python输入输出”这个主题,我把输入输出相关的知识点、常见坑位和实操套路一次讲透。

Python的输入输出,说白了就是程序和外部世界对话的两条通道:输入是程序接收你敲的键盘内容、读到的文件数据;输出是把计算结果展示在屏幕上、写进日志或者存到文件里。这套东西单独拎出来看好像没什么技术含量,但它决定了你写的脚本好不好用、能不能自动化、能不能跟其他系统对接。想用Python做数据处理、写自动化脚本、爬虫、甚至搞量化分析的人,这块是绕不过去的基础功。

下面我按自己踩坑总结的经验,从学习思路、核心语法、实操步骤到问题排查,一条线完整讲清楚。

1. 内容整体设计与思路拆解

1.1 先搞明白“输入输出”到底解决什么问题

我见过不少学员,学了半个月Python,问他input()和print()有什么用,他说“不就是让用户输东西、打印东西嘛”。这话对,但格局小了。

输入输出的本质是程序的数据边界。任何一段Python代码,不管逻辑多复杂,最终都逃不开三件事:拿数据、算数据、给数据。拿数据靠的就是输入机制,给数据靠的就是输出机制。如果输入输出的设计不合理,后面所有逻辑都白搭。举个最日常的例子:你写了个计算BMI的脚本,如果身高体重是写死在代码里的,那每次换个人测都得改代码重新跑;但如果用input()接收用户输入,这个脚本就能给任何人用。这就是输入输出最朴素的价值——把程序和具体数据解耦,让程序具备复用性。

Python官方文档里对输入输出的定义也很有意思:输入输出是程序与外部环境交互的主要途径,包括标准输入输出、文件I/O、网络I/O等。初学者阶段,我们主要接触的是标准输入输出(键盘、屏幕)和文件I/O(读写文件)。前者解决人机交互问题,后者解决数据持久化问题。

1.2 为什么Python的输入输出值得单独花一节课讲

说实话,单看语法,input()和print()都不难,难的是藏在背后的几个细节。

第一是类型问题。Python的input()不管你输入什么,返回的都是字符串。你想让用户输入年龄然后做加法,直接input()拿到的“18”是字符串,不能和数字直接相加,必须先int()转换。这个坑十个新手九个踩。

第二是格式化输出的选择。Python给字符串格式化提供了至少三种主流方式:%格式化、str.format()、f-string。到底用哪种?各有优劣,但f-string在Python 3.6以后几乎成了事实标准,简洁、直观、性能还好。很多人学的时候三种都混着用,代码风格不统一,回头维护起来很痛苦。

第三是文件读写要特别注意编码和资源释放问题。Python的open()如果忘了指定encoding='utf-8',Windows环境下跑出来的中文大概率乱码;如果忘了用with语句,文件句柄可能一直占用不释放。这些细节小但致命。

我会把内容分成三层来讲:基础语法层、格式化进阶层、文件与实战层。层层递进,每层都有配套的坑位提示,这样学完就能直接用。

2. 核心细节解析与实操要点

2.1 控制台输入的底层逻辑:input()不是你想的那样简单

input()的官方定义是:从标准输入读取一行文本,去除末尾的换行符,以字符串形式返回。注意,它永远返回字符串,不存在例外。

这里有几个很多人不知道的细节。input()可以接受一个字符串参数作为提示语,比如input("请输入你的名字:"),这个提示语会先打印到屏幕上,然后等待用户输入。有些老教程会让你先print("提示")再input(),那是多此一举,直接传参就行。

再一个细节是input()会阻塞程序运行,直到用户按下回车键才继续执行。这意味着如果你写了一个脚本,中间没有人来输入,程序就会一直卡在那里。在一些自动化场景里,这可能是好事(等用户确认),也可能是坏事(导致程序挂起)。我写自动化脚本时如果不需要交互,绝不使用input(),宁可直接在代码里写好参数或从文件读取。

另外要留意,input()读取的是“一行”,本身不会做任何类型转换和内容校验。用户输入多少就能拿到多少,哪怕用户输入的是乱码、空行,input()都照单全收。生产环境里,这个特性要求我们必须做输入校验。

2.2 print()输出的隐藏参数,用对了效率翻倍

print()可能是大家最早接触的函数,但它的完整签名很多老手也记不全。完整的print()签名是这样的:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

展开讲讲这些参数干什么用的。

sep参数是多个对象之间的分隔符,默认是一个空格。你print("a", "b")输出是“a b”,如果你想要“a,b”,传sep=','就行。这在把列表元素拼接成一行输出的时候非常有用,比循环加字符串拼接快多了。

end参数是输出末尾的字符,默认是换行符\n。很多人不知道可以改。比如你想连续打印多个结果但不换行,可以让end='';你想让多个print之间用空格隔开,可以让end=' '。写进度条或者需要动态刷新同一行内容的时候,end='\r'配合flush=True能做出很好的效果。

file参数是输出目标,默认是sys.stdout也就是屏幕。你可以传一个文件对象进去,让print()直接把内容写入文件,而不必手动write()。这在生成日志、导出报告时特别好用。举个小例子:

with open('log.txt', 'w', encoding='utf-8') as f: print('这是日志内容', file=f)

flush参数是是否强制刷新缓冲区,默认False。正常情况下print的内容先进缓冲区,等缓冲区满了或者程序结束时才会真正写到目标设备。在某些场景下(比如正在往管道里写数据,或者写进度条),你需要实时输出,就设置flush=True。

2.3 格式化输出的三种流派,我的推荐顺序很明确

格式化输出是输入输出模块里的重头戏,因为绝大多数场景下你不是打印一个裸数据,而是要拼一段有结构的文字。

最老的流派是%格式化。它从C语言的printf风格继承而来,用%s、%d、%f这些占位符。优点是兼容性好,Python所有版本都支持;缺点是参数多了以后可读性很差,容易写错。

name = "Alice" age = 25 print("我叫%s,今年%d岁" % (name, age))

第二种是str.format()方法。它用花括号{}做占位符,支持索引、命名参数等更灵活的方式。比%格式化可读性好一些,但写起来还是有点繁琐,尤其当参数很多时。

print("我叫{},今年{}岁".format(name, age)) print("我叫{name},今年{age}岁".format(name=name, age=age))

第三种是f-string,Python 3.6才引入的语法糖。在字符串前面加f,花括号里直接写变量名甚至表达式,写起来最直观,执行速度也快。我个人强烈建议新写的代码一律用f-string。

print(f"我叫{name},今年{age}岁") print(f"今年是{2025 - age}年出生的")

关于格式化还有一个格式规范值得一提,就是冒号后面跟格式说明。f-string里可以做数字对齐、补零、千分位分隔。

score = 0.8156 print(f"正确率:{score:.2%}") # 输出:正确率:81.56% print(f"金额:{1234567:,}") # 输出:金额:1,234,567 print(f"编号:{42:05d}") # 输出:编号:00042

这些操作在日常写报表、打印日志时非常常见,比来回转换强多了。

2.4 文件输入输出的核心:open()的mode参数要选对

除了屏幕上打打杀杀,输入输出的另一大块是文件读写。Python内置的open()函数是文件操作的大门。

open()最关键的参数有两个:文件路径和打开模式。模式决定了你要对文件做什么操作。常见的有:

  • r:只读模式,文件必须存在,否则报FileNotFoundError
  • w:写入模式,文件不存在就新建,存在就清空重写
  • a:追加模式,文件不存在就新建,存在就在末尾继续写
  • x:独占创建模式,文件已存在就报错,防止覆盖
  • rb/wb:二进制读写模式,处理图片、音频、视频等非文本文件
  • r+:读写模式,指针在文件开头

新手最容易踩的坑是混淆w和a。w会把原文件内容全部清空再写,如果你只是想追加内容,必须用a。我见过有人写脚本不小心用w模式覆盖了几天积累的数据,哭都来不及。

编码方面,open()默认编码是平台相关的,Windows下可能是gbk,Linux/macOS下一般是utf-8。为了统一,我写代码永远显式指定encoding='utf-8'。另外,尽量用with open() as f这种上下文管理器,它能自动关闭文件,避免资源泄漏。

# 推荐写法 with open('data.txt', 'r', encoding='utf-8') as f: content = f.read()
# 不推荐写法 f = open('data.txt', 'r') content = f.read() f.close()

第二种写法如果中间抛了异常,f.close()就不会执行,文件句柄就泄漏了。虽然程序退出后系统会回收,但长期运行的服务会越来越耗资源。

2.5 类型转换是实现输入输出的润滑剂

输入输出的过程中,类型转换就像一座桥。input()返回字符串,print()能接收任意类型(它会自动转成字符串打印),但你要做运算就不能拿字符串直接加数字。Python内置了几个常用的类型转换函数。

  • int(x):把x转成整数,如果x是字符串且内容不是纯数字,会抛ValueError
  • float(x):把x转成浮点数
  • str(x):把x转成字符串
  • list(x):把x转成列表
  • tuple(x):把x转成元组
  • bool(x):把x转成布尔值,需要注意空字符串、空列表、0、None都会转成False

这一块本身不难,难点在于“什么时候该转”。我的原则是:数据进来时尽量早转,数据出去时统一转字符串。不要在中间步骤里反复转换,既浪费性能又容易出错。

比如写计算平均分的脚本,用户输入三个成绩字符串,你先转成int存到列表里,最后求平均值,而不是每次比较前都现场转换。

scores = [] for i in range(3): s = int(input(f"请输入第{i+1}门课的成绩:")) scores.append(s) average = sum(scores) / len(scores) print(f"平均分:{average:.2f}")

3. 实操过程与核心环节实现

3.1 环境准备:先确认Python环境没问题

在开始写输入输出代码之前,先确保Python安装配置没问题。很多同学学到一半各种报错,最后发现是Python版本太老或环境变量没配好。

建议安装Python 3.8以上版本,因为f-string的调试功能(=号,比如f"{x=}")在3.8才加进来的。安装时务必勾选“Add Python to PATH”。装完打开终端或命令行,输入下面命令验证:

python --version

如果在Windows上弹出Windows商店或者什么都不输出,大概率是PATH没配好。如果输入python没反应,可以试试输入py --version,Windows上Python安装器会同时注册py启动器。

开发环境这块,我推荐VS Code加Python插件。不需要装太多扩展,Python官方插件就够了。配置也很简单,打开命令面板,输入“Python: Select Interpreter”,选择你自己的Python解释器即可。写完代码直接右键运行,或者在集成终端里python xxx.py运行,都比较顺。

3.2 从控制台交互开始:写一个用户信息录入脚本

基础语法光看是不行的,直接动手写个小项目最能加深理解。这里我设计一个用户信息录入脚本,把所有基础知识点都过一遍。

需求很简单:让用户输入姓名、年龄、城市、身高,然后按格式输出一段个人简介。

# user_info.py name = input("请输入姓名:") age = int(input("请输入年龄:")) city = input("请输入城市:") height = float(input("请输入身高(米):")) print(f"\n===== 个人信息 ======") print(f"姓名:{name}") print(f"年龄:{age}岁") print(f"城市:{city}") print(f"身高:{height}m") print(f"三年后的年龄:{age + 3}岁") print(f"成年与否:{'成年' if age >= 18 else '未成年'}") print(f"简介:我叫{name},来自{city},今年{age}岁,身高{height:.2f}米。")

几个值得展开的细节:

年龄我用int()转成整数,是为了后面能直接做加法,还能用条件表达式判断是否成年。身高用float(),是为了保留小数位,输出时用{height:.2f}控制保留两位小数。这就是典型的“数据进来时尽早转”的思路。

注意,如果用户输入的不是数字,比如年龄输入了“十八”,int("十八")会直接抛ValueError,程序当场崩溃。健壮一点的做法是用try/except捕获异常并提示用户重新输入。这个后面在问题排查章节我会专门展开。

3.3 格式化输出进阶:把日志系统的基础打好

日志是输入输出在真实项目中最常见的应用场景之一。很多人写日志用的是print()直接打印,临时调试可以,但真正要存留的时候就不够看了。我用一个日志格式化的例子,演示f-string和print()参数怎么配合使用。

import datetime def log(level, message): now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") print(f"[{now}][{level}] {message}", flush=True) log("INFO", "用户登录成功") log("ERROR", "数据库连接超时")

这段代码虽然简单,但里面有个细节值得学:strftime()是时间格式化的方法,它把时间对象转成指定格式的字符串。这个在日志输出中几乎是标配。

如果你想把日志同时写到文件和控制台,可以利用print()的file参数:

import sys import datetime log_file = open('app.log', 'a', encoding='utf-8') def log(level, message): now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") line = f"[{now}][{level}] {message}" print(line, flush=True) # 输出到控制台 print(line, file=log_file, flush=True) # 写入日志文件 log("INFO", "系统启动") log("WARNING", "内存使用率偏高,请注意") log("ERROR", "配置文件缺失")

这里我故意用open()而不是with,是因为log函数里需要多次写入,如果每次都用with打开关闭,性能损耗大。但这种写法要求你在程序结束前手动调用log_file.close(),否则最后的数据可能没刷新到磁盘。

实际项目中更推荐用logging模块,但理解print()的file参数能帮你明白logging模块底层在做什么。

3.4 文件读写实战:实现一个电影收藏管理器

接下来做一个稍微完整的小项目:电影收藏管理器。功能包括:显示当前收藏、添加新电影、保存到文件、从文件读取。

先定义两个函数,分别负责保存和加载数据。数据用CSV格式存储,每一行是一部电影的标题、导演、评分。

# movie_manager.py import os DATA_FILE = "movies.csv" def load_movies(): if not os.path.exists(DATA_FILE): return [] movies = [] with open(DATA_FILE, "r", encoding="utf-8") as f: for line in f: line = line.strip() if not line: continue parts = line.split(",") if len(parts) == 3: title, director, rating = parts movies.append({"title": title, "director": director, "rating": float(rating)}) return movies def save_movies(movies): with open(DATA_FILE, "w", encoding="utf-8") as f: for m in movies: f.write(f"{m['title']},{m['director']},{m['rating']}\n") def show_movies(movies): if not movies: print("暂无收藏电影,快去添加吧。") return print(f"{'标题':<15}{'导演':<10}{'评分':>5}") print("-" * 30) for m in movies: print(f"{m['title']:<15}{m['director']:<10}{m['rating']:>5.1f}") def add_movie(movies): title = input("请输入电影标题:") director = input("请输入导演:") rating = float(input("请输入评分(0-10):")) movies.append({"title": title, "director": director, "rating": rating}) print(f"电影《{title}》已添加。") def main(): movies = load_movies() while True: print("\n===== 电影收藏管理器 =====") print("1. 显示所有电影") print("2. 添加新电影") print("3. 保存并退出") choice = input("请选择操作:") if choice == "1": show_movies(movies) elif choice == "2": add_movie(movies) elif choice == "3": save_movies(movies) print("数据已保存,再见!") break else: print("无效选择,请输入1-3。") if __name__ == "__main__": main()

这段代码把前面讲的输入输出知识全部揉进去了。

input()接收用户操作选择,虽然这里没转int,直接用字符串比较,也是可以的。show_movies()里用f-string的格式规范控制对齐:{m['title']:<15}表示左对齐占15个字符宽度,{m['rating']:>5.1f}表示右对齐5个字符宽度且保留1位小数。这些细节让输出在控制台里像表格一样整齐。

文件读写部分有两个关键点。load_movies()里的line.strip()是去掉行尾的换行符,否则存进去的title会带一个\n;split(",")把一行数据拆成三块。save_movies()里用f-string把字典的值拼接成CSV行。整个过程没有用csv模块,是为了让你看到底层的字符串处理逻辑,实际项目用csv模块更稳妥。

如果你忘了with open会帮你close文件,还是手动加close的话,写文件时如果程序中途崩溃,数据可能就没写完。with语法能最大限度避免这个问题。

3.5 用代码块展示完整效果与预期输出

上面这个小项目写完后,正常情况下运行效果大概是这样的:

请输入电影标题:流浪地球2 请输入导演:郭帆 请输入评分(0-10):8.3 电影《流浪地球2》已添加。 ===== 电影收藏管理器 ===== 1. 显示所有电影 2. 添加新电影 3. 保存并退出 请选择操作:1 标题 导演 评分 ------------------------------ 流浪地球2 郭帆 8.3

注意在Windows的cmd里,中文字符的显示宽度和英文字符不一样,用中文占位可能对不齐,这个是终端字体的问题,不是代码的问题。实际测试如果发现列没对齐,别慌,要么换等宽字体,要么在输出里少用中文对齐。

4. 常见问题与排查技巧实录

4.1 ValueError: invalid literal for int()

这是新手最经常撞见的报错。当你写int(input()),并且用户输入的不是纯数字时,Python就抛这个错。

比如用户本来该输入年龄,结果手滑输入了“18岁”,int("18岁")就失败了。解决方案有两个层面。

第一个是主动防御,在转换前先判断字符串是否由数字组成:

age_str = input("请输入年龄:") if age_str.isdigit(): age = int(age_str) else: print("输入不合法,请输入纯数字")

第二个是异常捕获,更健壮,适合写大程序:

while True: try: age = int(input("请输入年龄:")) break except ValueError: print("输入不合法,请输入纯数字")

while True配合try/except是输入校验的经典套路,能保证用户直到输入正确为止才能往下走。如果是在考试或作业里,异常捕获会比isdigit()拿到的分更多,因为它考虑到了程序运行的鲁棒性。

4.2 中文乱码问题:编码格式混战

写文件时打印中文变成了乱码,十有八九是编码问题。Windows默认的GBK和Linux/macOS的UTF-8互相不认,这是历史遗留问题。

最直接的解决方案:所有文件读写一律显式指定encoding='utf-8'。不要偷懒,不要相信系统默认值。代码里写文件时:

with open('output.txt', 'w', encoding='utf-8') as f: f.write("中文内容")

读文件时:

with open('output.txt', 'r', encoding='utf-8') as f: content = f.read()

两边编码一致,就不会乱码。如果读的是从网上下载的数据,不确定对方用的什么编码,可以尝试用gbk解码,或者用chardet库先检测编码。但在自己写的项目里,统一UTF-8是基本素养。

还有一个小坑:在用print()往Windows的控制台输出中文时,如果控制台代码页不是UTF-8,也可能显示乱码。这种情况不是代码的问题,是Windows控制台的编码问题。你可以在代码开头加一句:

import sys import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

不过这种写法在有些环境下会出问题,更推荐直接改控制台为UTF-8模式,或者在VS Code里运行,基本就没有乱码烦恼了。

4.3 输入卡住不动、按回车没反应怎么办

很多人第一次写input(),运行的时候发现光标一直在闪,输什么都没反应,然后怀疑程序卡死了。其实不是,是input()在等待你输入,而且你必须输入完成后按回车才算结束。

如果你觉得程序“卡住”了,检查一下当前是不是有input()在运行。解决办法很简单:在提示语里告诉用户“请按回车确认”,让使用的人心里有数。比如:

input("按回车键继续...")

这个写法在脚本暂停、查看中间结果时非常常用。有些程序在Windows上跑,小黑窗一结束就关闭,看不到输出结果,大家习惯在脚本末尾加上面这句,让窗口保持打开。

另外注意input()本身不接收“任意键”,它必须等回车键。如果你要监听特定键盘事件(比如按q退出),input()办不到,需要第三方库比如keyboard或pynput,那是另一个话题了。

4.4 文件写入后内容不显示:缓冲区刷新问题

有同学遇到过这种情况:用write()写完文件,马上用记事本打开,发现内容是空的;过一会儿再打开,内容又出现了。这个“诡异”现象其实是缓冲区在作怪。

write()并不是把数据立即写到磁盘,而是先写进内存缓冲区。缓冲区满了或文件关闭时才会真正写入磁盘。如果你用with open()写,退出with块时文件会被自动close,数据也会被刷新到磁盘,一般不会有这个问题。但如果你用f = open()后一直不关闭,又立刻读文件,就可能读到空内容。

解决办法是写入后立即刷新缓冲区:

f.flush()

或者干脆写成with结构,让它自动管理。我自己的习惯是:能with就with,尽量减少手动flush和close的时机。

还有一个类似的问题,print()在管道模式下可能不实时输出。比如你运行python script.py | more,屏幕上看不到输出,要过一会儿才冒出来。这就是print的缓冲在作怪,加flush=True可以强制实时输出。

4.5 关于CSV文件的一个隐秘坑位

我在前面示例里用split(",")解析CSV行,有个隐藏问题没说:如果电影标题本身包含逗号,比如“蜘蛛侠:英雄远征,还是啥”,split(",")会把一行拆成4段,len(parts) != 3,这一行就会被丢弃。

这种问题在实际数据处理中非常常见,因为CSV的字段是可以带逗号的,字段用引号包裹。为了解决这个问题,Python内置的csv模块是更好的选择:

import csv with open('movies.csv', 'r', encoding='utf-8') as f: reader = csv.DictReader(f, fieldnames=['title', 'director', 'rating']) for row in reader: movies.append(row)

写入时:

with open('movies.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.DictWriter(f, fieldnames=['title', 'director', 'rating']) writer.writeheader() writer.writerows(movies)

csv模块能正确处理引号、逗号、换行等特殊情况。不要因为简单的例子就用split硬拼,一旦数据复杂化,维护成本直线上升。我在实际工作中,凡是处理表格型数据,一律用csv模块,不手写解析逻辑。

4.6 输入输出常见问题速查表

问题现象可能原因解决方案
int(input()) 报错用户输入了非数字内容用try/except或isdigit()做校验
中文写文件乱码编码不匹配读写都显式指定encoding='utf-8'
程序运行后没有输出print缓冲未刷新加flush=True或退出with块
文件写入后内容为空缓冲区未落盘用with自动close,或手动flush()
打开文件提示文件不存在路径错误或模式用错检查路径,用写入模式先创建文件
控制台中文对不齐中英文宽字符不一致换等宽字体,或减少中文排版

这张表是我在实际教学和项目经验里总结出来的最高频问题。遇到问题先对应着查,能省很多排错时间。

5. 进一步扩展:用输入输出搭建更实用的脚本

5.1 让输入输出自动化起来:重定向标准输入输出

控制台输入输出不仅能手动操作,还能用重定向机制自动化。在Linux/macOS或Windows的命令行中,你可以把文件内容作为程序输入,把程序输出重定向到文件。

python calculate.py < input.txt > output.txt

这行命令的意思是:calculate.py的input()不再从键盘读,而是直接从input.txt里逐行读取;print()的输出全部写入output.txt。这种方式非常利于批量处理数据和自动化测试。

举个实际例子,你写了一个计算器脚本,想快速测试100组数据,手动一组组输入肯定不现实。这时你把测试数据按行写入input.txt,跑一次重定向命令,结果全部到output.txt,比手动操作高效太多了。

顺带一提,这个机制也是OJ(在线评测系统)的核心原理。你在刷算法题时,题目给定的输入样例本质上就是扔给程序的标准输入流,而程序打印的结果要和标准答案比对。理解了标准输入输出重定向,你自然就明白OJ为什么能自动评判代码了。

5.2 从txt到JSON:用json模块扩展文件输出格式

CSV适合表格型数据,但遇到嵌套结构的数据就不方便了。JSON是另一种极其常用的文件格式,Python的json模块内置支持,读写都只有一行代码。

import json movies = [ {"title": "流浪地球2", "director": "郭帆", "rating": 8.3}, {"title": "星际穿越", "director": "诺兰", "rating": 9.4} ] # 写入JSON文件 with open('movies.json', 'w', encoding='utf-8') as f: json.dump(movies, f, ensure_ascii=False, indent=2) # 读取JSON文件 with open('movies.json', 'r', encoding='utf-8') as f: loaded_movies = json.load(f)

注意写入时的ensure_ascii=False,如果不加,默认会把中文转成\uXXXX格式的转义序列,文件里全是乱码一样的东西,肉眼没法读。indent=2参数让JSON格式化打印,便于人阅读。这在对接API、保存配置、做数据交换时非常常用。

5.3 用输入输出做数据统计分析:实用小案例

最后放一个综合案例:从CSV文件读取全班同学的数学成绩,统计最高分、最低分、平均分、及格率,并把统计结果写入报告文件。

import csv def load_scores(filepath): scores = [] with open(filepath, 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: scores.append({ "name": row["姓名"], "score": int(row["成绩"]) }) return scores def analyze(scores): values = [s["score"] for s in scores] total = sum(values) count = len(values) avg = total / count passed = sum(1 for v in values if v >= 60) pass_rate = passed / count return { "最高分": max(values), "最低分": min(values), "平均分": round(avg, 2), "及格率": f"{pass_rate:.2%}" } def write_report(stats, filepath): with open(filepath, 'w', encoding='utf-8') as f: for key, value in stats.items(): f.write(f"{key}:{value}\n") def main(): scores = load_scores("scores.csv") stats = analyze(scores) print(stats) write_report(stats, "report.txt") if __name__ == "__main__": main()

这里的核心是无处不在的输入输出:load_scores()是文件输入,analyze()是数据处理,write_report()是文件输出,print(stats)是控制台输出。一个简单的数据分析流程被拆得清清楚楚,每个环节的输入输出边界都很明确。

如果你要处理的数据量更大,比如几十万行,用纯Python跑也能跑,但性能上会差一些,这时可以考虑换成Pandas,它内部的读取和输出API设计思路和Python内置的是一致的,理解了原生的输入输出,过渡到Pandas会非常平滑。

6. 写在最后的实操心得

我在这几年的项目中反复写输入输出,最大的感受就是:这块内容看似简单,但它决定了代码的“对外接口”好不好用。你在团队里写一个模块,别人怎么调用你的程序?无非就是传参数、读文件、看输出。输入输出设计得好,合作起来就顺;设计得糙,后面全是沟通成本。

有个习惯我强烈建议养成:所有对外输出都走统一格式。比如日志里时间统一用YYYY-MM-DD HH:MM:SS,数值统一用两位小数,布尔值统一打印成“是/否”。这能让你的脚本看起来专业得多,排查问题的时候也容易对齐时间线。我见过太多临时脚本今天print这个格式、明天print那个格式,回头一看根本没法对数据,这是典型的输出设计失败。

编码问题上也再啰嗦一句:只要是读写文本文件,一律带encoding='utf-8',不要信任任何平台默认值。这句话值不值钱,等你在Windows上被乱码折磨得抓狂的时候就知道了。

最后再分享一个小技巧:调试输入输出,可以用一个小技巧快速验证逻辑。你需要调试一个input()函数,但又不想每次手动输入测试数据,可以在运行命令里重定向输入:

python -c "print('测试')" > temp_input.txt python your_script.py < temp_input.txt

这样脚本会自动读取temp_input.txt内容作为输入,你不用一遍遍打字,调试效率高很多。输入输出这条线如果学得扎实,后面学文件处理、爬虫、数据分析都会顺畅很多,因为所有东西最终都要落到“怎么把数据拿进来、怎么把结果送出去”这个基本框架上。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 4:34:48

开源AI编程代理opencode实战:安装配置、IDE联动与团队使用指南

最近好几个读者问我 opencode 到底能不能打&#xff0c;正好我这两天也在鼓捣它&#xff0c;就把安装、配置、接手老项目、接 IDE 这一整套流程都过了一遍。先说结论&#xff1a;opencode 是一个跑在终端里的开源 AI 编程代理&#xff0c;你可以把它理解成 Claude Code、Codex …

作者头像 李华
网站建设 2026/9/8 4:33:27

PHP+MySQL游戏聚合站部署全攻略:源码包到1500+游戏上线

简介&#xff1a;一个以PHP和MySQL为核心技术栈的在线游戏网站源码包&#xff0c;适用于具备基础编程能力、希望完整经历动态网站开发全流程的初学者&#xff0c;也适合正在做课程设计或毕业设计的学生参考。站点主体包含1500余款游戏数据&#xff0c;具备前台展示、分类点选、…

作者头像 李华
网站建设 2026/9/8 4:33:23

架构假设如何变成可执行代码?从评审到测试的落地指南

我做代码评审这些年&#xff0c;最常遇到的场景不是代码写得差&#xff0c;而是架构图画得漂亮&#xff0c;代码却完全是另一回事。架构师在评审会上说&#xff1a;“订单服务必须在 200 毫秒内返回&#xff0c;我们基于这个超时假设做降级。”开发同学点头“明白”&#xff0c…

作者头像 李华
网站建设 2026/9/8 4:31:50

开源雷达周刊2026-W35:开源动态、项目精选与工程避坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/8 4:31:14

Java基础入门:从环境配置到集合框架的完整避坑指南

最近后台收到不少私信&#xff0c;问的全是同一个问题&#xff1a;“想学 Java&#xff0c;到底从哪里开始&#xff1f;为什么我照着教程敲代码&#xff0c;还是一堆报错&#xff1f;” 我太懂这种感觉了&#xff0c;当年第一次配环境变量的时候&#xff0c;照着网上教程一步步…

作者头像 李华
网站建设 2026/9/8 4:31:12

随机森林算法原理与Matlab实现:从手写代码到工具箱调参

简介&#xff1a;压缩包内是MATLAB环境下随机森林&#xff08;RF&#xff09;的完整实现&#xff0c;面向需要进行分类与回归建模的机器学习学习者与工程师&#xff0c;解决模型训练、预测与特征重要性评估等常见需求。包内共14个文件、211KB&#xff0c;主要包含MATLAB函数、示…

作者头像 李华