查看全课大纲(第 45 / 51 节)
- 1.为什么人人都该学点编程?
- 2.计算机与程序设计:你的电脑到底在“想”什么?
- 3.Python 这门语言,到底有什么魔力?
- 4.Python 开发环境配置:如何拥有你的第一个“编程工具箱”?
- 5.如何安装一个更强大的代码编辑器?
- 6.汇率兑换1.0:你的第一个“钱生钱”小程序
- 7.你的第一行代码,藏着哪些秘密?
- 8.汇率兑换2.0(上):让程序看懂“CNY”和“USD”
- 9.汇率兑换程序,如何让它“聪明”地判断币种?
- 10.汇率兑换程序能一直运行,直到我喊停吗?
- 11.汇率兑换4.0:如何把“算钱”功能打包成积木?
- 12.汇率兑换5.0:给你的程序穿上“结构化”的西装
- 13.怎么用 Python 画一个会动的五角星?
- 14.如何让程序自动画出不同大小的五角星?
- 15.函数自己调用自己,会发生什么?
- 16.用递归画出神奇的分形树
- 17.Python 怎么计算你一天躺着不动能消耗多少热量?
- 18.如何让程序“活”起来,持续为你服务?
- 19.如何让 BMR 计算器更“聪明”?
- 20.当程序遇到“不按套路出牌”的用户怎么办?
- 21.怎么用 Python 模拟一个“滚雪球”式的存钱计划?
- 22.如何用列表记录每一周的存款?
- 23.如何让程序自己数数?—— 用 for 循环解放你的双手
- 24.52周存钱挑战4.0:你的存款计算器能有多灵活?
- 25.52周存钱挑战:怎么根据日期自动查存款?
- 26.Python 怎么判断一年中的第几天?
- 27.列表 vs 元组:哪个更适合存储月份天数?
- 28.用集合给月份分个队,换个思路算天数
- 29.把月份和天数“锁”在一起:用字典给数据配个对
- 30.Python 怎么判断密码强弱?
- 31.Python 怎么给密码设置“防沉迷”系统?
- 32.Python 怎么把密码保存到文件里?
- 33.Python 怎么读取文件里的密码?
- 34.Python 怎么把密码检查工具“打包”起来?
- 35.Python 怎么把文件操作也“打包”起来?
- 36.计算机怎么“扔骰子”?——用Python模拟随机事件
- 37.如何用 Python 模拟掷两个骰子?
- 38.怎么用 Python 把骰子轨迹画出来?
- 39.骰子点数分布长啥样?用直方图一眼看穿!
- 40.用科学计算库让骰子程序“起飞”
- 41.空气质量指数怎么算?手把手教你写一个AQI计算器
- 42.空气质量指数计算:从零开始,让程序看懂空气
- 43.如何读取空气质量数据文件并找出空气质量最好的五个监测点?
- 44.JSON 数据怎么变成 Excel 表格?—— 让数据换个“马甲”
- 45.Python 怎么让程序自己判断文件类型?
- 46.如何让程序自己上网查空气质量?
- 47.用美味的汤来解析网页:Beautiful Soup 入门
- 48.如何让爬虫自动抓取全国所有城市的空气质量?
- 49.爬到的数据怎么存下来?—— 把全国空气质量数据保存为CSV文件
- 50.用 pandas 玩转空气质量数据:找出全国空气最好和最差的城市
- 51.空气质量数据怎么“洗”干净,还能画成图?
Python 怎么让程序自己判断文件类型?
约 11 分钟
小象实战讲义 · Python 入门:8 个小项目边玩边学
你好呀!欢迎来到空气质量指数计算项目的第 4 步。在前两节里,我们学会了用 Python 读取 JSON 和 CSV 这两种格式的数据文件。现在,我们来玩点更酷的:写一个“聪明”的程序,让它自己判断你给的文件是 JSON 还是 CSV,然后自动用正确的方法打开它!
想象一下,你有一个文件夹,里面既有 .json 文件,也有 .csv 文件。你不想每次打开前都手动判断,而是希望程序能自动帮你搞定。这就是我们这节课要实现的“文件格式自动识别器”。
💡 核心导读
本节我们将一起完成:
- 认识一位新朋友:
os模块,它能帮我们轻松获取文件的扩展名(比如.json或.csv)。 - 学会一个更优雅的文件操作方式:
with语句,从此再也不用担心忘记关闭文件了! - 整合之前的知识,用
if...elif...else判断文件类型,并调用对应的处理函数。 - 本节新增了什么? 我们只新增了
os.path.splitext()这个函数来提取文件扩展名,并用with语句优化了文件操作。其他都是老朋友啦!
1. 回顾与目标:让程序“聪明”起来
在前两节,我们分别写了处理 JSON 文件的程序和处理 CSV 文件的程序。但它们是分开的。如果我想处理一个文件,还得先看看它是什么格式,再决定运行哪个程序,这太不“智能”了。
我们这节课的目标,就是写一个统一的入口程序。你只需要告诉它文件名,它就能自己判断格式,并调用正确的处理逻辑。
案例描述:编写一个程序,根据用户输入的文件路径,自动判断该文件是 JSON 格式还是 CSV 格式,并分别进行读取和内容展示。
2. 新技能:用 os 模块获取文件信息
怎么判断一个文件是 .json 还是 .csv 呢?最直接的办法就是看文件名最后那几个字符(也就是扩展名)。Python 的 os 模块里有一个超好用的工具 os.path.splitext(),专门干这个。
os 模块是 Python 和操作系统打交道的“瑞士军刀”,可以干很多事,比如创建文件夹、删除文件、检查路径等等。我们今天只请它帮一个小忙。
# 让我们先感受一下 os.path.splitext() 的魔力
import os
# 假设我们有一个文件路径
file_path = "上海空气质量.json"
# 使用 splitext 分割
filename, file_ext = os.path.splitext(file_path)
print(f"文件名部分是:{filename}")
print(f"扩展名部分是:{file_ext}")文件名部分是:上海空气质量
扩展名部分是:.json看!它把文件名和扩展名干净利落地分开了,而且扩展名是带点(.) 的。这样我们判断起来就非常方便了。
3. 再学一招:更安全的文件操作 with
还记得我们操作文件的“三步曲”吗?打开 → 操作 → 关闭。有时候一忙起来,很容易忘记最后那步 close(),这可能会导致资源没被释放。
Python 提供了一个更优雅、更安全的写法:with 语句。它的好处是,无论文件操作是否成功,是否发生错误,它都会在代码块结束后自动帮你关闭文件。再也不用担心忘记关文件啦!
我们来对比一下新旧写法:
import os
# 本节需要 example.txt(课程 resources 附件提供);为便于单独运行,先用示例数据建一份
with open('example.txt', 'w', encoding='utf-8') as f: # 示例数据:每次运行都重建,保证输出一致
f.write("拼接后的完整路径是:data\\\\test.csv\n多层目录拼接:project\\\\data\\\\2023\\\\result.json")
# 旧写法:需要手动关闭
f = open('example.txt', 'r')
content = f.read()
print(content)
f.close() # 容易忘记!
# 新写法(推荐!):使用 with 语句
with open('example.txt', 'r') as f:
content = f.read()
print(content)
# 出了 with 这个代码块,文件会自动关闭,不需要写 f.close()拼接后的完整路径是:data\\test.csv
多层目录拼接:project\\data\\2023\\result.json
拼接后的完整路径是:data\\test.csv
多层目录拼接:project\\data\\2023\\result.json是不是简洁又安心?我们这节课就会用这个新写法来重写文件处理部分。
4. 动手实现:文件格式自动判断程序
好了,新工具都准备好了,让我们把它们组装起来,写出我们的 v4.0 程序。
核心思路:
- 获取用户输入的文件名。
- 用
os.path.splitext()提取扩展名。 - 判断扩展名:
- 如果是
.json,就调用处理 JSON 的函数。 - 如果是
.csv,就调用处理 CSV 的函数。 - 如果都不是,就提示用户格式不支持。
- 如果是
- 在处理函数中,使用
with语句安全地读取文件。
下面是完整的程序,我们把 JSON 和 CSV 的处理逻辑分别封装成了函数。
"""
作者:小象教研组
功能:AQI计算 - 自动判断文件格式 (v4.0)
版本:4.0
"""
import json
import csv
import os
# 本节需要 上海空气质量.json(课程 resources 附件提供);为便于单独运行,先用示例数据建一份
with open('上海空气质量.json', 'w', encoding='utf-8') as f: # 示例数据:每次运行都重建,保证输出一致
f.write('[{"aqi": "51", "area": "北京"}, {"aqi": "102", "area": "顺义"}]')
def process_json_file(filepath):
"""
处理json文件:读取并打印内容
"""
# 使用 with 语句,安全又省心
with open(filepath, mode='r', encoding='utf-8') as f:
# json.load() 可以直接从文件对象读取数据
city_list = json.load(f)
print("=== JSON 文件内容 ===")
print(city_list)
def process_csv_file(filepath):
"""
处理csv文件:读取并打印每一行
"""
# 注意:csv读取时指定 newline='' 可以避免空行问题
with open(filepath, mode='r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
print("=== CSV 文件内容(每行是一个列表)===")
for row in reader:
# row 是一个列表,我们用逗号把它连接成一个字符串打印
print(', '.join(row))
def main():
"""
主函数:判断文件格式并分发处理
"""
# 原程序这里用 input(),为了你能直接运行,我们先给一个固定值
# 你可以改成 '上海空气质量.json' 或 '上海空气质量.csv' 试试
filepath = '上海空气质量.json'
# 使用 os.path.splitext 获取扩展名
filename, file_ext = os.path.splitext(filepath)
print(f"正在检查文件:{filepath}")
print(f"检测到扩展名:{file_ext}")
# 根据扩展名决定如何处理
if file_ext == '.json':
print("识别为 JSON 文件,开始处理...")
process_json_file(filepath)
elif file_ext == '.csv':
print("识别为 CSV 文件,开始处理...")
process_csv_file(filepath)
else:
print(f'抱歉,不支持 {file_ext} 格式的文件!')
# 启动程序
main()正在检查文件:上海空气质量.json
检测到扩展名:.json
识别为 JSON 文件,开始处理...
=== JSON 文件内容 ===
[{'aqi': '51', 'area': '北京'}, {'aqi': '102', 'area': '顺义'}]代码说明:
process_json_file和process_csv_file函数封装了各自格式的处理细节,主程序main()变得非常清晰。- 在
process_csv_file中,我们用了', '.join(row)。join()是字符串的方法,它能把一个列表里的所有元素,用指定的字符串(这里是', ')连接起来,变成一个新的字符串。这样打印出来更美观。 - 主逻辑就是一个清晰的
if-elif-else判断,根据file_ext的值来“派活”。
运行一下看看: 你需要准备两个小文件来测试。我们这里用内联数据模拟一下文件内容,实际练习时你可以用课程提供的真实数据文件。
# 模拟测试:我们先在代码里创建两个临时文件内容来演示
import json
import csv
import os
from io import StringIO
# 模拟一个JSON文件内容
json_data = [
{"城市": "上海", "AQI": 65},
{"城市": "北京", "AQI": 120}
]
json_str = json.dumps(json_data, ensure_ascii=False)
# 模拟一个CSV文件内容
csv_data = "城市,AQI,等级\n上海,65,良\n北京,120,轻度污染"
# 为了演示,我们使用 StringIO 来模拟文件对象,避免真的读写磁盘
print("--- 模拟处理 JSON 文件 ---")
with StringIO(json_str) as f:
city_list = json.load(f)
print(city_list)
print("\n--- 模拟处理 CSV 文件 ---")
with StringIO(csv_data) as f:
reader = csv.reader(f)
for row in reader:
print(', '.join(row))--- 模拟处理 JSON 文件 ---
[{'城市': '上海', 'AQI': 65}, {'城市': '北京', 'AQI': 120}]
--- 模拟处理 CSV 文件 ---
城市, AQI, 等级
上海, 65, 良
北京, 120, 轻度污染看,程序成功地区分并处理了两种格式!当你把第 40 行的 filepath 改成 '上海空气质量.csv' 时,它就会自动调用 CSV 处理函数。
5. 程序进化图:我们走到了哪一步?
让我们回顾一下这个项目的成长历程:
- v1.0:学会了计算 AQI 的数学公式。
- v2.0:学会了从 JSON 文件读取数据并排序输出。
- v3.0:学会了把 JSON 数据转换成 CSV 格式并保存。
- v4.0(本节):程序变“聪明”了! 能自动判断文件类型,并用更优雅(
with)的方式处理文件。
我们的程序从一个只会算数的小计算器,变成了一个能灵活处理多种数据文件的“小管家”。
📝 动手练一练
扩展名判断增强:我们的程序目前只认识
.json和.csv。如果用户输入了一个.txt文本文件,程序会说格式不支持。请你修改一下main()函数中的判断部分,让它能识别.txt文件,并简单地用f.read()打印出文件的所有文本内容。路径拼接小能手:
os.path.join()函数可以智能地拼接路径,避免手动写斜杠/或反斜杠\(在不同操作系统上不一样)。例如,os.path.join('folder', 'data.json')在 Windows 上会得到folder\data.json,在 Mac/Linux 上会得到folder/data.json。请你写一小段代码,假设有一个基础目录'data'和一个文件名'test.csv',使用os.path.join()生成完整的文件路径并打印出来。
👉 点击查看第1题参考答案
思路:在 main() 函数的 if-elif-else 判断中,增加一个 elif 分支来处理 .txt 扩展名。在这个分支里,调用一个新的函数(比如 process_txt_file)来读取并打印文本文件。
# 新增的处理 txt 文件的函数
def process_txt_file(filepath):
"""处理纯文本文件"""
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
print("=== 文本文件内容 ===")
print(content)
# 在 main() 函数的判断部分增加一个分支
def main():
filepath = 'example.txt' # 假设这是一个文本文件
filename, file_ext = os.path.splitext(filepath)
if file_ext == '.json':
process_json_file(filepath)
elif file_ext == '.csv':
process_csv_file(filepath)
elif file_ext == '.txt': # 新增的判断
print("识别为文本文件,开始处理...")
process_txt_file(filepath)
else:
print(f'不支持 {file_ext} 格式的文件!')👉 点击查看第2题参考答案
思路:直接使用 os.path.join() 函数,传入两个字符串参数,它会返回拼接好的路径。
import os
base_dir = 'data'
filename = 'test.csv'
full_path = os.path.join(base_dir, filename)
print(f"拼接后的完整路径是:{full_path}")
# 你可以试试更多层目录
full_path2 = os.path.join('project', 'data', '2023', 'result.json')
print(f"多层目录拼接:{full_path2}")拼接后的完整路径是:data\test.csv
多层目录拼接:project\data\2023\result.json本章小结
恭喜!你又解锁了两个非常实用的 Python 技能:
os.path.splitext():轻松获取文件扩展名,是判断文件类型的神器。with语句:文件操作的“安全卫士”,自动管理资源的打开和关闭,代码更简洁、更健壮。
你把之前分散的 JSON 和 CSV 处理能力整合了起来,写出了一个会自己判断、自己行动的“智能”程序。这种感觉是不是很棒?
📋 行动清单
学完本节,你可以立刻:
- 运行今天的 v4.0 程序,分别用
.json和.csv文件测试它。 - 尝试修改程序,让它支持一种新的文件格式(比如
.txt)。 - 在你自己的其他小程序里,把文件操作的
open...close改成with语句,体验一下它的简洁。
我们的空气质量数据目前还是“静态”的,是提前准备好的文件。下一节,我们要玩点更刺激的:让程序自己去网上抓取最新的、实时的空气质量数据! 这就是传说中的“网络爬虫”入门。敬请期待!
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。