文章目录

    • 读取文件
      • 读取文件的全部内容
    • 相对路径和绝对路径
    • 访问文件中的各行
    • 使用文件的内容
    • 包含100万位的大型文件
    • 圆周率值中包含你的生日吗?
  • 写入文件
    • 写入一行
    • 写入多行
  • 异常
    • 处理ZeroDivisionError异常
    • 使用try-except代码块
    • else代码块
    • 处理FileNotFoundError异常
    • 分析文本
    • 使用多个文件
    • 静默失败
    • 决定报告哪些错误
  • 存储数据
    • 使用json.dump()和json.load()
    • 保存和读取用户生成的数据
    • 重构
  • 往期
  • 代码仓库

从第一到第十章,我们学习了编写程序的所需的基本技能。

在本章节中,我们将学习如何处理文件,以及如何使用异常处理错误。

读取文件

文本文件可以存储许多数据:天气数据、交通数据、社会经济数据、文学作品等。

要使用文本文件中的信息,首先需要将信息读取到内存中。既可以一次性读取文件的全部内容,也可以逐行读取。

读取文件的全部内容

我们先准备一个文件,名为pi_digits.txt,内容如下:

3.141592653589793238462643383279

然后我们开始编写第一个读取文件的代码file_reader.py:

from pathlib import Pathpath = Path('pi_digits.txt')
contents = path.read_text()
print(contents)

要使用文件的内容,需要将其路径告知 Python。
路径(path)是文件或文件夹在系统中的准确位置。
Python 提供了 pathlib 模块,能处理各种操作系统中处理文件和目录。

首先中 pathlib 模块导入 Path 类,再使用 Path 对像指向一个文件。
这里创建了一个表示文件 pi_digits.txt 的 Path 对象,并将其赋给了变量 path由于这个文件与当前编写的 .py 文件位于同一个目录中,因此 Path 只需要知道其文件名就能访问它。

创建表示文件 pi_digits.txt 的 Path 对象后,使用 read_text() 方法来读取这个文件的全部内容。
**read_text()**将该文件的全部内容作为一个字符串返回。我们将这个字符串赋给了变量 contents,再将其打印出来。

相比原始原件,输出唯一不同的地方是末尾多了一个空行。
因为 read_text()在到达文件末尾时会返回一个空字符串,而这个空字符串会被显示一个空行。
要删除这个多出来的空行,可对字符串变量contents调用 strip() 方法。

contents = path.read_text().rstrip()

这种方式称为方法链式调用。

博主使用的 3.13版本已经没有了这个问题。

相对路径和绝对路径

指定路径的方式有两种:

  • 相对文件路径让 Python 到相对于当前运行的程序文件所在的目录去查找。
  • 绝对文件路径让 Python 去系统的准确位置去查找。

在相对路径行不通时,可使用绝对路径。

绝对路径通常比相对路径长,因为以系统的根文件夹为起点。
在 Linux 系统中,系统的根文件夹为 /,而在 Windows 系统中,系统的根文件夹为 C:\。


path = Path('/home/eric/data_files/text_files/filename.txt')

在 Windows 系统中,可使用反斜杠(\)而不是斜杠(/)来分隔路径中的文件夹。

访问文件中的各行

使用 splitlines() 方法将冗长的字符串转换为一系列行,再使用 for 循环以每次一行的方式检查文件中的各行

from pathlib import Pathpath = Path('pi_digits.txt')
contents = path.read_text()lines = contents.splitlines()
for line in lines:print(line)

和前面一样,读取文件的全部内容,由于没有修改行,因此输出与文件内容相同。

使用文件的内容

将文件的内容读取到内存中后,就可以以任何方式使用这些数据了。

首先,创建一个字符串,它包含文件中存储的所有数字。

from pathlib import Pathpath = Path('pi_digits.txt')
contents = path.read_text()lines = contents.splitlines()
# 创建变量 pi_string
pi_string = ''
for line in lines:pi_string += lineprint(pi_string)
print(len(pi_string))

输出如下:

3.1415926535  8979323846  2643383279
32

变量pi_string存储的字符串包含原来位于每行左端的空格。要删除这些空格,可对每行调用lstrip()方法。

for line in lines:pi_string += line.lstrip()

输出如下:

3.141592653589793238462643383279
32

注意:在读取文本文件时,Python将其中的所有文本都解释为字符串。
如果读取的是数字,并要将其作为数值使用,就必须使用函数 int() 将其转换为整数,或使用函数 float() 将其转换为浮点数。

包含100万位的大型文件

如果一个文本文件包含精确到小数点后 1 000 000 位而不是 30 位的圆周率值,也可以创建一个包含所有这些数字的字符串。

在这个例子中,我们将使用一个包含 100 000 位的圆周率值的文本文件,该文件的第一行只包含前 50 位。

from pathlib import Pathpath = Path('pi_million_digits.txt')
contents = path.read_text()
lines = contents.splitlines()
pi_string = ''
for line in lines:pi_string += line.lstrip()print(f"{pi_string[:52]}...")
print(len(pi_string))

圆周率值中包含你的生日吗?

现在我们知道如何使用 Python 来读取文件,我们来编写一个程序,看看圆周率值中包含你的生日吗?

from pathlib import Pathpath = Path('pi_million_digits.txt')
contents = path.read_text()
lines = contents.splitlines()
pi_string = ''
for line in lines:pi_string += line.lstrip()
birthday = input("Enter your birthday, in the form mmddyy: ")
if birthday in pi_string:print("Your birthday appears in the first million digits of pi!")
else:print("Your birthday does not appear in the first million digits of pi.")

写入文件

保存数据的最简单的方式之一是将其写入文件。

写入一行

定义一个文件的路径后,就可使用 write_text() 将数据写入该文件了。

from pathlib import Pathpath = Path("programming.txt")
# write_text() 方法接受单个实参,即要写入文件的字符串。
path.write_text("I love programming.\n")

。这个程序没有终端输出,但你如果打开文件 programming.txt。

注意:Python 只能将字符串写入文本文件。要将数值数据存储到文本文件中,必须先使用函数 str() 将其转换为字符串格式。

写入多行

write_text() 方法会在幕后完成几项工作。

首先,如果 path 变量对应的路径指向的文件不存在,就创建它。
其次,将字符串写入文件后,它会确保文件得以妥善地关闭。

要将多行写入文件,需要先创建一个字符串(其中包含要写入文件的全部内容),再调用 write_text() 并将这个字符串传递给它。

from pathlib import Path
contents = "I love programming.\n"
contents += "I love creating new games.\n"
contents += "I also love working with data.\n"path = Path('programming.txt')
path.write_text(contents)

在对 path 对象调用 write_text() 方法时,务必谨慎。如果指定的文件已存在, write_text() 将删除其内容,再将指定的文本写入其中。

异常

Python 使用称为异常(exception)的特殊对象来管理程序执行期间发生的错误。

异常是使用 try-except 代码块处理的。

处理ZeroDivisionError异常

print(5/0)

输出如下:

Traceback (most recent call last):File "C:\Users\Administrator\PycharmProjects\pythonProject\demo.py", line 1, in <module>print(5/0)  # 报错
ZeroDivisionError: division by zero

在上述 traceback 中,错误 ZeroDivisionError 是个异常对象。
Python 在无法按你的要求做时,就会创建这种对象。

使用try-except代码块

try:print(5/0)
except ZeroDivisionError:print("You can't divide by zero!")

输出如下:

You can't divide by zero!

当你认为可能发生了错误时,可编写一个 try 语句来告诉 Python,你要执行的操作可能引发这种错误。

else代码块

只有 try 代码块成功执行才需要继续执行的代码,都应放到 else 代码块中


--snip - -
while True:--snip - -if second_number == 'q':break
try:answer = int(first_number) / int(second_number)
except ZeroDivisionError:print("You can't divide by 0!")
else:print(answer)

如果除法运算成功,就使用 else 代码块来打印结果

处理FileNotFoundError异常

在使用文件时,一种常见的问题是找不到文件:要查找的文件可能在其他地方,文件名可能不正确,或者这个文件根本就不存在。

from pathlib import Pathpath = Path('alice.txt')
contents = path.read_text(encoding='utf-8')

这里使用 read_text() 的方式与前面稍有不同。如果系统的默认编码与要读取的文件的编码不一致,参数 encoding 必不可少。

Python 无法读取不存在的文件,因此引发了一个异常FileNotFoundError

通常最好从 traceback 的末尾着手。从最后一行可知,引发了异常 FileNotFoundError。

from pathlib import Pathpath = Path('alice.txt')
try:contents = path.read_text(encoding='utf-8')
except FileNotFoundError:print(f"Sorry, the file {path} does not exist.")

这个示例中,try 代码块中的代码引发了 FileNotFoundError 异常,因此要编写一个与该异常匹配的 except 代码块。
这样,当找不到文件时,Python 将运行 except 代码块中的代码,从而显示一条友好的错误消息,而不是 traceback。

分析文本

from pathlib import Pathpath = Path('alice.txt')
try:contents = path.read_text(encoding='utf-8')
except FileNotFoundError:print(f"Sorry, the file {path} does not exist.")
else:# 计算文件大致包含多少个单词words = contents.split()num_words = len(words)print(f"The file {path} has about {num_words} words.")

仅当 try 代码块成功执行时才会执行它们。输出指出了文件 alice.txt 包含多少个单词。

使用多个文件

下面分析几本书

from pathlib import Pathdef count_words(filename):"""计算一个文件大致包含多少个单词。"""try:contents = Path(filename).read_text(encoding='utf-8')except FileNotFoundError:msg = f"Sorry, the file {filename} does not exist."print(msg)else:# 计算文件大致包含多少个单词。words = contents.split()num_words = len(words)print(f"The file {filename} has about {num_words} words.")filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:count_words(filename)

先将文件名存储为简单字符串,然后将每个字符串转换为 Path 对象,再调用 count_words()。

在这个示例中,使用 try-except 代码块有两个重要的优点:一是避免用户看到 traceback,二是让程序可以继续分析能够找到的其他文件。

静默失败

Python 有一个 pass 语句,可在代码块中使用它来让 Python 什么都不做。

def count_words(path):"""计算一个文件大致包含多少个单词"""try:--snip--except FileNotFoundError:passelse:--snip--

当这种错误发生时,既不会出现 traceback,也没有任何输出。用户将看到存在的每个文件包含多少个单词,但没有任何迹象表明有一个文件未找到

决定报告哪些错误

只要程序依赖于外部因素,如用户输入、是否存在指定的文件、是否有网络连接,就有可能出现异常。凭借经验可判断该在程序的什么地方包含异常处理块,以及出现错误时该向用户提供多少相关的信息。

存储数据

一种简单的方式是使用模块 json 来存储数据。

使用json.dump()和json.load()

第一个程序将使用 json.dumps() 来存储这组数,而第二个程序将使用 json.loads() 来读取它们。

from pathlib import Path
import jsonnumbers = [2,3,5,7,11,13]path = Path('numbers.json')
contents = json.dumps(numbers)
path.write_text(contents)

首先导入模块 json,并创建一个数值列表。然后选择一个文件名,指定要将该数值列表存储到哪个文件中。
接下来,使用 json.dumps() 函数生成一个字符串,将其存储到变量 contents 中。
最后,使用 Path 对象的 write_text() 方法将这个字符串写入到文件 numbers.json 中。

使用 json.loads() 将这个列表读取到内存中

from pathlib import Path
import jsonpath = Path('numbers.json')
contents = path.read_text()
numbers = json.loads(contents)
print(numbers)

这个数据文件是使用特殊格式的文本文件,因此可使用 read_text() 方法来读取它。然后将这个文件的内容传递给 json.loads()。这个函数将一个 JSON 格式的字符串作为参数,并返回一个 Python 对象(这里是一个列表),而我们将这个对象赋给了变量 numbers。最后,打印恢复的数值列表

保存和读取用户生成的数据

使用 json 保存用户生成的数据很有必要

from pathlib import Path
import json# 首先,提示用户输入名字
username = input("请输入你的用户名:")# 接下来,将收集到的数据写入文件 username.json
path = Path('username.json')
contents = json.dump(username)
path.write_text(contents)# 然后,打印一条消息,指出存储了用户输入的信息
print(f"我们将记住你的用户名,{username}")

再编写一个程序,向名字已被存储的用户发出问候

from pathlib import Path
import jsonpath = Path('username.json')
contents = path.read_text()
username = json.loads(contents)print(f"欢迎回来,{username}!")

我们读取数据文件的内容,并使用 json.loads() 将恢复的数据赋给变量 userusername

from pathlib import Path
import jsonpath = Path('username.json')
# 如果指定的文件或文件夹存在,exists() 方法返回 True,否则返回 False。
# 这里使用 path.exists() 来确定是否存储了用户名
if path.exists():# 如果文件 username.json 存在,就加载其中的用户名,并向用户发出个性化问候contents = path.read_text()username = json.loads(contents)print(f"欢迎回来,{username}!")
else:# 如果文件 username.json 不存在,就提示用户输入用户名,并存储用户输入的值。username = input("请输入你的用户名:")contents = json.dumps(username)path.write_text(contents)print(f"我们将记住你的用户名,{username}")

重构

虽然代码能够正确地运行,但还可以将其划分为一系列完成具体工作的函数来进行改进。这样的过程称为重构。

重构让代码更清晰、更易于理解、更容易扩展。

from pathlib import Path
import jsondef greet_user():"""问候用户,并指出其名字。"""path = Path('users.json')if path.exists():contents = path.read_text()username = json.loads(contents)print(f'欢迎回来{username}')else:username = input('请输入你的名字:')contents = json.dumps(username)path.write_text(contents)print(f'我们将记住你的名字{username}')greet_user()

greet_user() 函数所做的不仅是问候用户,还在存储了用户名时获取它,在没有存储用户名时提示用户输入。
下面重构 greet_user(),不让它执行这么多任务。

from pathlib import Path
import json# 如果存储了用户名,就获取并返回它;如果传递给 get_stored_username() 的路径不存在,就返回 None
def get_stored_username(path):"""如果存储了用户名,就获取它"""if path.exists():contents = path.read_text()username = json.loads(contents)return usernameelse:# 这是一种不错的做法:函数要么返回预期的值,要么返回 None。return Nonedef get_stored_username(path):"""提示用户输入用户名"""username = input('请输入你的名字? ')contents= json.dumps(username)path.write_text(contents)return usernamedef greet_user():"""问候用户,并指出其名字"""path = Path('username.json')username = get_stored_username(path)if username:print(f"Welcome back, {username}!")else:username = get_stored_username(path)print(f"We'll remember you when you come back, {username}!")greet_user()

在 remember_me.py 的这个最终版本中,每个函数都执行单一而清晰的任务。我们调用 greet_user(),它打印一条合适的消息:要么欢迎老用户回来,要么问候新用户。

首先调用 get_stored_username(),这个函数只负责获取已存储的用户名(如果存储了),再在必要时调用 get_new_username(),这个函数只负责获取并存储新用户的用户名。要编写出清晰且易于维护和扩展的代码,这种划分必不可少。


往期

  • Python3完全新手小白的学习手册 9 类
  • Python3完全新手小白的学习手册 8 函数
  • Python3完全新手小白的学习手册 7 用户输入和while循环
  • Python3完全新手小白的学习手册 6 字典
  • Python3完全新手小白的学习手册 5 if语句
  • Python3完全新手小白的学习手册 4 操作列表
  • Python3完全新手小白的学习手册 3 列表
  • Python3完全新手小白的学习手册 2 变量和简单数据类型
  • Python3完全新手小白的学习手册 1 Python 的安装

代码仓库

代码仓库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/87120.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/87120.shtml
英文地址,请注明出处:http://en.pswp.cn/web/87120.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VC Spyglass:工具简介

相关阅读 VC Spyglasshttps://blog.csdn.net/weixin_45791458/category_12828932.html?spm1001.2014.3001.5482 传统上&#xff0c;基于仿真的动态验证技术一直是功能验证的核心方式。随着现代SoC设计日益复杂&#xff0c;静态验证技术的引入变得愈发重要。 Synopsys的 VC Sp…

AWS RDS Aurora全局数据库转区域数据库实战指南:无缝迁移零停机

Aurora全局数据库是AWS提供的跨区域高可用解决方案,但在某些场景下,我们需要将其转换为普通区域数据库。本文将详细介绍这一转换过程,并分享关键技术要点和实战经验。 一、全局数据库与区域数据库概述 AWS RDS Aurora全局数据库是一种跨区域部署的数据库架构,主要用于灾备…

C++之路:函数重载与运算符重载

目录 函数重载运算符重载C运算符重载范围对照表注意事项 运算符重载语法全局运算符重载类内运算符重载下面以一个一元运算符为例&#xff0c;介绍特性1&#xff1a;下面介绍特性3&#xff1a;&#xff08;必须类内重载的运算符‌&#xff09; 函数重载 函数重载是指同一个作用域…

七、SpringCloud 项目迁移至 K8s

七、SpringCloud 项目迁移至 K8s 文章目录 七、SpringCloud 项目迁移至 K8s1、环境准备1.1 集群规划1.2 SpringCloud 项目架构及迁移需求分析 2、迁移 Eureka 集群2.1 构建及容器化2.2 部署至 K8s2.3 创建通信Service 3、迁移网关服务3.1 构建及容器化3.2 部署至 K8s3.3 创建Se…

通过具有一致性嵌入的大语言模型实现端到端乳腺癌放射治疗计划制定|文献速递-最新论文分享

Title 题目 End-to-end breast cancer radiotherapy planning via LMMs with consistency embedding 通过具有一致性嵌入的大语言模型实现端到端乳腺癌放射治疗计划制定 01 文献速递介绍 近年来&#xff0c;受大型语言模型&#xff08;LLM&#xff09;启发的新一代人工智…

MCP Chart Server服务本地部署案例

一、MCP Chart Server介绍 MCP Chart Server是一个专业的图表生成服务&#xff0c;支持多种图表类型&#xff0c;适用于数据可视化和分析。 MCP Chart Server是一种用于生成和呈现图表的服务器端软件。它提供了一个简单而强大的方式&#xff0c;让开发人员和系统管理员可以轻…

复合型浪涌保护器五大核心技术重构电气防护体系

开篇&#xff1a;从传统防护到智能守护的技术跨越 在电气设备面临浪涌威胁的防护场景中&#xff0c;浪涌保护器&#xff08;SPD&#xff09;始终扮演着关键角色。面对传统SPD在漏电流、续流等方面的技术局限&#xff0c;行业领先企业通过技术整合开发出复合型SPD&#xff0c;以…

c# 详细分析Task.sleep和Thread.sleep 的区别、使用场景和应用示例

文章目录 Task.Delay vs Thread.Sleep 详细分析与使用场景核心区别详细分析Thread.SleepTask.Delay 性能考量综合示例高级用法组合延迟与超时实现指数退避重试 总结建议 Task.Delay vs Thread.Sleep 详细分析与使用场景 核心区别 Task.Delay 和 Thread.Sleep 都用于在代码中引…

Vue 3 中的 `h` 函数详解

h 函数是 Vue 3 中用于创建**虚拟 DOM 节点(VNode)**的核心函数&#xff0c;它是 Vue 渲染系统的基石。下面我将全面解释它的作用、用法和重要性。 1. h 函数的基本概念 h 是 createVNode 的简称&#xff0c;来源于"hyperscript"的缩写传统。它的主要作用是&#x…

SoapCore 全面介绍:在 .NET Core 中实现 SOAP 服务的现代解决方案

一、什么是 SoapCore&#xff1f; 在现代微服务和 REST API 成为主流的今天&#xff0c;SOAP&#xff08;Simple Object Access Protocol&#xff09;看似已经被边缘化&#xff0c;但在许多企业和政务系统中&#xff0c;SOAP 仍然是 重要的通信协议。特别是在金融、保险、医疗…

JDBC工具类和SQL 注入问题

在软件开发中&#xff0c;数据库安全与高效访问一直是关键课题。本文将围绕 SQL 注入问题的原理、解决方案&#xff0c;以及 JDBC 开发中的工具类演进和连接池技术展开探讨&#xff0c;结合实际代码示例&#xff0c;为开发者提供清晰的技术实践指南。 SQL 注入问题的核心原理与…

2022年SEVC SCI2区,分数阶蚁群算法FACA:一种基于分数阶长期记忆的合作学习方法,深度解析+性能实测

目录 1.摘要2.分数阶微积分基础知识3.分数阶蚁群算法FACA4.分数阶蚁群算法FACA数学证明与分析5.结果展示6.参考文献7.代码获取8.算法辅导应用定制读者交流 1.摘要 本文提出了一种新颖分数阶蚁群算法&#xff08;Fractional-Order Ant Colony Algorithm&#xff0c; FACA&#…

java+vue+SpringBoo数字科技风险报告管理系统(程序+数据库+报告+部署教程+答辩指导)

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿ppt部署教程代码讲解代码时间修改工具 技术实现 开发语言&#xff1a;后端&#xff1a;Java 前端&#xff1a;vue框架&#xff1a;springboot数据库&#xff1a;mysql 开发工具 JDK版本&#xff1a;JDK1.…

YOLOv12_ultralytics-8.3.145_2025_5_27部分代码阅读笔记-augment.py

augment.py ultralytics\data\augment.py 目录 augment.py 1.所需的库和模块 2.class BaseTransform: 3.class Compose: 4.class BaseMixTransform: 5.class CutMix(BaseMixTransform): 6.class CopyPaste(BaseMixTransform): 7.def v8_transforms(dataset, img…

跨芯片 AI 算子库 FlagGems 正式加入PyTorch 基金会生态项目体系

2025年北京智源大会 PyTorch Day China 论坛上&#xff0c;PyTorch 基金会执行董事 Matt White 宣布高性能通用 AI 算子库 FlagGems 项目获得批准&#xff0c;正式加入 PyTorch 生态项目体系。Pytorch基金会于6月26日在推特上进行了官方宣布。 作为唯一支持多种AI芯片架构的算…

vue + vue-router写登陆验证的同步方法和异步方法,及页面组件的分离和后端代码

先写一个用vue cdn写一个登陆验证的小示例后端代码 前端719.html <div id"app"><div id"loginForm">//路由层&#xff0c;登陆页和后台主页<router-link to"/">Login</router-link><router-link to"/home&quo…

.netcore 一个mvc到静态html实现

一、新建Mvc项目 Program.cs添加拦截 二、添加一个集成测试 将页面转为html到wwwroot下面 UnitGenHtml.cs using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.VisualStudio.TestPlatform.TestHost;namespace SaaS.OfficialWeb…

实现Taro小程序+nut-ui左滑删除效果

Taro小程序开发中&#xff0c;使用nut-ui组件&#xff0c;实现左滑删除卡片效果&#xff08;自定义删除按钮样式&#xff09; html代码部分 <nut-swipe class"carBox" v-for"(item, index) in carList" :key"item" :ref"(el) > se…

LLM 系列(五):模型训练篇

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…

Oracle LogMiner分析日志的三种方法示例

Oracle LogMiner分析日志的三种方法示例 方法一:Online Catalog作为日志挖掘字典自动获取日志模式手动获取日志模式方法二:Redo Log作为日志挖掘字典自动获取日志模式手动获取日志模式方法三:Flat File作为日志挖掘字典自动获取日志模式手动获取日志模式📖 Oracle LogMine…