10 - Python文件编程和异常

文件和异常

在实际开发中,常常需要对程序中的数据进行持久化操作,而实现数据持久化最直接简单的方式就是将数据保存到文件中。说到“文件”这个词,可能需要先科普一下关于文件系统的知识,对于这个概念,维基百科上给出了很好的诠释,这里不再浪费笔墨。

在Python中实现文件的读写操作其实非常简单,通过Python内置的open函数,我们可以指定文件名、操作模式、编码信息等来获得操作文件的对象,接下来就可以对文件进行读写操作了。这里所说的操作模式是指要打开什么样的文件(字符文件还是二进制文件)以及做什么样的操作(读、写还是追加),具体的如下表所示。

操作模式具体含义
'r'读取 (默认)
'w'写入(会先截断之前的内容)
'x'写入,如果文件已经存在会产生异常
'a'追加,将内容写入到已有文件的末尾
'b'二进制模式
't'文本模式(默认)
'+'更新(既可以读又可以写)

下面这张图来自于菜鸟教程网站,它展示了如果根据应用程序的需要来设置操作模式。

在这里插入图片描述

读写文本文件

读取文本文件时,需要在使用open函数时指定好带路径的文件名(可以使用相对路径或绝对路径)并将文件模式设置为'r'(如果不指定,默认值也是'r'),然后通过encoding参数指定编码(如果不指定,默认值是None,那么在读取文件时使用的是操作系统默认的编码),如果不能保证保存文件时使用的编码方式与encoding参数指定的编码方式是一致的,那么就可能因无法解码字符而导致读取失败。下面的例子演示了如何读取一个纯文本文件。

def main():f = open('致橡树.txt', 'r', encoding='utf-8')print(f.read())f.close()if __name__ == '__main__':main()

请注意上面的代码,如果open函数指定的文件并不存在或者无法打开,那么将引发异常状况导致程序崩溃。为了让代码有一定的健壮性和容错性,我们可以使用Python的异常机制对可能在运行时发生状况的代码进行适当的处理,如下所示。

def main():f = Nonetry:f = open('致橡树.txt', 'r', encoding='utf-8')print(f.read())except FileNotFoundError:print('无法打开指定的文件!')except LookupError:print('指定了未知的编码!')except UnicodeDecodeError:print('读取文件时解码错误!')finally:if f:f.close()if __name__ == '__main__':main()

在Python中,我们可以将那些在运行时可能会出现状况的代码放在try代码块中,在try代码块的后面可以跟上一个或多个except来捕获可能出现的异常状况。例如在上面读取文件的过程中,文件找不到会引发FileNotFoundError,指定了未知的编码会引发LookupError,而如果读取文件时无法按指定方式解码会引发UnicodeDecodeError,我们在try后面跟上了三个except分别处理这三种不同的异常状况。最后我们使用finally代码块来关闭打开的文件,释放掉程序中获取的外部资源,由于finally块的代码不论程序正常还是异常都会执行到(甚至是调用了sys模块的exit函数退出Python环境,finally块都会被执行,因为exit函数实质上是引发了SystemExit异常),因此我们通常把finally块称为“总是执行代码块”,它最适合用来做释放外部资源的操作。如果不愿意在finally代码块中关闭文件对象释放资源,也可以使用上下文语法,通过with关键字指定文件对象的上下文环境并在离开上下文环境时自动释放文件资源,代码如下所示。

def main():try:with open('致橡树.txt', 'r', encoding='utf-8') as f:print(f.read())except FileNotFoundError:print('无法打开指定的文件!')except LookupError:print('指定了未知的编码!')except UnicodeDecodeError:print('读取文件时解码错误!')if __name__ == '__main__':main()

除了使用文件对象的read方法读取文件之外,还可以使用for-in循环逐行读取或者用readlines方法将文件按行读取到一个列表容器中,代码如下所示。

import timedef main():# 一次性读取整个文件内容with open('致橡树.txt', 'r', encoding='utf-8') as f:print(f.read())# 通过for-in循环逐行读取with open('致橡树.txt', mode='r') as f:for line in f:print(line, end='')time.sleep(0.5)print()# 读取文件按行读取到列表中with open('致橡树.txt') as f:lines = f.readlines()print(lines)if __name__ == '__main__':main()

要将文本信息写入文件文件也非常简单,在使用open函数时指定好文件名并将文件模式设置为'w'即可。注意如果需要对文件内容进行追加式写入,应该将模式设置为'a'。如果要写入的文件不存在会自动创建文件而不是引发异常。下面的例子演示了如何将1-9999直接的素数分别写入三个文件中(1-99之间的素数保存在a.txt中,100-999之间的素数保存在b.txt中,1000-9999之间的素数保存在c.txt中)。

from math import sqrtdef is_prime(n):"""判断素数的函数"""assert n > 0for factor in range(2, int(sqrt(n)) + 1):if n % factor == 0:return Falsereturn True if n != 1 else Falsedef main():filenames = ('a.txt', 'b.txt', 'c.txt')fs_list = []try:for filename in filenames:fs_list.append(open(filename, 'w', encoding='utf-8'))for number in range(1, 10000):if is_prime(number):if number < 100:fs_list[0].write(str(number) + '\n')elif number < 1000:fs_list[1].write(str(number) + '\n')else:fs_list[2].write(str(number) + '\n')except IOError as ex:print(ex)print('写文件时发生错误!')finally:for fs in fs_list:fs.close()print('操作完成!')if __name__ == '__main__':main()

读写二进制文件

知道了如何读写文本文件要读写二进制文件也就很简单了,下面的代码实现了复制图片文件的功能。

def main():try:with open('guido.jpg', 'rb') as fs1:data = fs1.read()print(type(data))  # <class 'bytes'>with open('吉多.jpg', 'wb') as fs2:fs2.write(data)except FileNotFoundError as e:print('指定的文件无法打开.')except IOError as e:print('读写文件时出现错误.')print('程序执行结束.')if __name__ == '__main__':main()

读写JSON文件

通过上面的讲解,我们已经知道如何将文本数据和二进制数据保存到文件中,那么这里还有一个问题,如果希望把一个列表或者一个字典中的数据保存到文件中又该怎么做呢?答案是将数据以JSON格式进行保存。JSON是“JavaScript Object Notation”的缩写,它本来是JavaScript语言中创建对象的一种字面量语法,现在已经被广泛的应用于跨平台跨语言的数据交换,原因很简单,因为JSON也是纯文本,任何系统任何编程语言处理纯文本都是没有问题的。目前JSON基本上已经取代了XML作为异构系统间交换数据的事实标准。关于JSON的知识,更多的可以参考JSON的官方网站,从这个网站也可以了解到每种语言处理JSON数据格式可以使用的工具或三方库,下面是一个JSON的简单例子。

{'name': '骆昊','age': 38,'qq': 957658,'friends': ['王大锤', '白元芳'],'cars': [{'brand': 'BYD', 'max_speed': 180},{'brand': 'Audi', 'max_speed': 280},{'brand': 'Benz', 'max_speed': 320}]
}

可能大家已经注意到了,上面的JSON跟Python中的字典其实是一样一样的,事实上JSON的数据类型和Python的数据类型是很容易找到对应关系的,如下面两张表所示。

JSONPython
objectdict
arraylist
stringstr
number (int / real)int / float
true / falseTrue / False
nullNone
PythonJSON
dictobject
list, tuplearray
strstring
int, float, int- & float-derived Enumsnumber
True / Falsetrue / false
Nonenull

我们使用Python中的json模块就可以将字典或列表以JSON格式保存到文件中,代码如下所示。

import jsondef main():mydict = {'name': '骆昊','age': 38,'qq': 957658,'friends': ['王大锤', '白元芳'],'cars': [{'brand': 'BYD', 'max_speed': 180},{'brand': 'Audi', 'max_speed': 280},{'brand': 'Benz', 'max_speed': 320}]}try:with open('data.json', 'w', encoding='utf-8') as fs:json.dump(mydict, fs)except IOError as e:print(e)print('保存数据完成!')if __name__ == '__main__':main()

json模块主要有四个比较重要的函数,分别是:

  • dump - 将Python对象按照JSON格式序列化到文件中
  • dumps - 将Python对象处理成JSON格式的字符串
  • load - 将文件中的JSON数据反序列化成对象
  • loads - 将字符串的内容反序列化成Python对象

这里出现了两个概念,一个叫序列化,一个叫反序列化。自由的百科全书维基百科上对这两个概念是这样解释的:“序列化(serialization)在计算机科学的数据处理中,是指将数据结构或对象状态转换为可以存储或传输的形式,这样在需要的时候能够恢复到原先的状态,而且通过序列化的数据重新获取字节时,可以利用这些字节来产生原始对象的副本(拷贝)。与这个过程相反的动作,即从一系列字节中提取数据结构的操作,就是反序列化(deserialization)”。

目前绝大多数网络数据服务(或称之为网络API)都是基于HTTP协议提供JSON格式的数据,关于HTTP协议的相关知识,可以看看阮一峰老师的《HTTP协议入门》,如果想了解国内的网络数据服务,可以看看聚合数据和阿凡达数据等网站,国外的可以看看{API}Search网站。下面的例子演示了如何使用requests模块(封装得足够好的第三方网络访问模块)访问网络API获取国内新闻,如何通过json模块解析JSON数据并显示新闻标题,这个例子使用了天行数据提供的国内新闻数据接口,其中的APIKey需要自己到该网站申请。

import requests
import jsondef main():resp = requests.get('http://api.tianapi.com/guonei/?key=APIKey&num=10')data_model = json.loads(resp.text)for news in data_model['newslist']:print(news['title'])if __name__ == '__main__':main()

在Python中要实现序列化和反序列化除了使用json模块之外,还可以使用pickle和shelve模块,但是这两个模块是使用特有的序列化协议来序列化数据,因此序列化后的数据只能被Python识别。关于这两个模块的相关知识可以自己看看网络上的资料。另外,如果要了解更多的关于Python异常机制的知识,可以看看segmentfault上面的文章《总结:Python中的异常处理》,这篇文章不仅介绍了Python中异常机制的使用,还总结了一系列的最佳实践,很值得一读。

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

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

相关文章

亚马逊云科技AWS免费大热AI应用开发证书(含题库、开卷)

亚马逊云科技AWS官方生成式AI免费证书来了&#xff01;内含免费AI基础课程&#xff01;快速掌握AWS的前沿AI技术&#xff0c;后端开发程序员也可以速成AI专家&#xff0c;了解当下最&#x1f525;的AWS AI架构解决方案&#xff01; 本证书内容包括AWS上的AI基础知识&#xff0c…

剖析DeFi交易产品之UniswapV4:Swap

文章首发于公众号&#xff1a;Keegan小钢 Swap 可分为两种场景&#xff1a;单池交易和跨池交易。在 PoolManager 合约里&#xff0c;要完成交易流程&#xff0c;会涉及到 lock()、swap()、settle()、take() 四个函数。单池交易时只需要调一次 swap() 函数&#xff0c;而跨池交易…

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(七)-shell语法(5)

shell语法的一些知识和练习&#xff0c;可以当作笔记收藏一下&#xff01;&#xff01; 文章目录 前言 一、shell 二、shell语法 1.文件重定向 2.引入外部脚本 3.作业 总结 前言 shell语法的一些知识和练习&#xff0c;可以当作笔记收藏一下&#xff01;&#xff01; 提示&…

七种大模型微调方法:让你的Offer拿到爽

在当今的人工智能和机器学习领域&#xff0c;大型预训练模型&#xff08;如GPT、BERT等&#xff09;已成为解决自然语言处理&#xff08;NLP&#xff09;任务的强大工具。然而&#xff0c;要让这些模型更好地适应特定任务或领域&#xff0c;往往需要进行微调。本文将详细介绍七…

手把手教你:如何在51建模网免费下载3D模型?

作为国内领先的3D互动展示平台&#xff0c;51建模网不仅汇聚了庞大的3D模型资源库&#xff0c;供用户免费下载&#xff0c;更集成了在线编辑、格式转换、内嵌展示及互动体验等一站式功能&#xff0c;为3D创作者及爱好者搭建起梦想与现实的桥梁。 如何在51建模网免费下载3D模型…

鸿蒙认证值得考吗?

鸿蒙认证值得考吗&#xff1f; 鸿蒙认证&#xff08;HarmonyOS Certification&#xff09;是华为为了培养和认证开发者在鸿蒙操作系统&#xff08;HarmonyOS&#xff09;领域的专业技能而设立的一系列认证项目。这些认证旨在帮助开发者和企业工程师提升在鸿蒙生态中的专业技能…

linux——IPC 进程间通信

IPC 进程间通信 interprocess communicate IPC&#xff08;Inter-Process Communication&#xff09;&#xff0c;即进程间通信&#xff0c;其产生的原因主要可以归纳为以下几点&#xff1a; 进程空间的独立性 资源隔离&#xff1a;在现代操作系统中&#xff0c;每个进程都…

图解 Kafka 架构

写在前面 Kafka 是一个可横向扩展&#xff0c;高可靠的实时消息中间件&#xff0c;常用于服务解耦、流量削峰。 好像是 LinkedIn 团队开发的&#xff0c;后面捐赠给apache基金会了。 kafka 总体架构图 Producer&#xff1a;生产者&#xff0c;消息的产生者&#xff0c;是消息的…

怎么把录音转文字?推荐几个简单易操作的方法

在小暑这个节气里&#xff0c;炎热的天气让人分外渴望效率up&#xff01;Up&#xff01;Up&#xff01; 对于那些在会议或课堂中急需记录信息的朋友们&#xff0c;手写笔记的速度往往难以跟上讲话的节奏。此时&#xff0c;电脑录音转文字软件就像一阵及时雨&#xff0c;让记录…

PHP pwn 学习 (1)

文章目录 A. PHP extensions for C1. 运行环境与工作目录初始化2. 构建与加载3. 关键结构定义PHP_FUNCTIONINTERNAL_FUNCTION_PARAMETERSzend_execute_data等ZEND_PARSE_PARAMETERS_START等zend_parse_arg_stringzend_module_entryzend_function_entry等PHP类相关 原文链接&…

Python 作业题1 (猜数字)

题目 你要根据线索猜出一个三位数。游戏会根据你的猜测给出以下提示之一&#xff1a;如果你猜对一位数字但数字位置不对&#xff0c;则会提示“Pico”&#xff1b;如果你同时猜对了一位数字及其位置&#xff0c;则会提示“Fermi”&#xff1b;如果你猜测的数字及其位置都不对&…

Flower花所:稳定运营的数字货币交易所

Flower花所是一家稳定运营的数字货币交易所&#xff0c;致力于为全球用户提供安全、高效的数字资产交易服务。作为一家长期稳定运营的数字货币交易平台&#xff0c;Flower花所以其可靠的技术基础和优质的客户服务而闻名。 平台稳定性与可靠性&#xff1a; 持续运营&#xff1a;…

Vue前端练习

此练习项目只涉及前端&#xff0c;主要是vue和ElementUI框架的使用。&#xff08;ElementUI官网&#xff1a;Element - The worlds most popular Vue UI framework&#xff09; 一、环境准备 安装idea 安装Node.js 一键式安装(不需要做任何配置) npm -v&#xff08;也可用nod…

mysql-sql-第十五周

学习目标&#xff1a; sql 学习内容&#xff1a; 41.查询没有学全所有课程的同学的信息 select *from students where students.stunm not in (select score.stunm from score group by score.stunm having count(score.counm) (select count(counm) from course)) 42.查询…

数据结构_线性表

线性表的定义和特点 线性表是具有相同特性的数据元素的一个有限序列 :线性起点/起始节点 :的直接前驱 :的直接后继 :线性终点/终端节点 n:元素总个数,表长 下标:是元素的序号,表示元素在表中的位置 n0时称为空表 线性表 由n(n>0)个数据元素(结点),组成的有限序列 将…

安卓模拟器如何修改ip地址

最近很多老铁玩游戏的&#xff0c;想多开模拟器一个窗口一个IP&#xff0c;若模拟器窗口开多了&#xff0c;IP一样会受到限制&#xff0c;那么怎么更换自己电脑手机模拟器IP地址呢&#xff0c;今天就教大家一个修改模拟器IP地址的方法&#xff01;废话不多说&#xff0c;直接上…

alibaba EasyExcel 简单导出数据到Excel

导入依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>4.0.1</version> </dependency> 1、alibaba.excel.EasyExcel导出工具类 import com.alibaba.excel.EasyExcel; import …

探索哈希函数:数据完整性的守护者

引言 银行在处理数以百万计的交易时&#xff0c;如何确保每一笔交易都没有出错&#xff1f;快递公司如何跟踪成千上万的包裹&#xff0c;确保每个包裹在运输过程中没有丢失或被替换&#xff1f;医院和诊所为庞大的患者提供有效的医疗保健服务&#xff0c;如何确保每个患者的医疗…

假阳性和假阴性、真阳性和真阴性

在深度学习的分类问题中&#xff0c;真阳性、真阴性、假阳性和假阴性是评估模型性能的重要指标。它们的定义和计算如下&#xff1a; 真阳性&#xff08;True Positive, TP&#xff09;&#xff1a; 定义&#xff1a;模型预测为正类&#xff08;阳性&#xff09;&#xff0c;且实…

电梯修理升级,安装【电梯节能】能量回馈设备

电梯修理升级&#xff0c;安装【电梯节能】能量回馈设备 1、节能率评估 15%—45% 2、降低机房环境温度&#xff0c;改善电梯控制系统的运行环境&#xff1b; 3、延长电梯使用寿命&#xff1b; 4、机房可以不需要使用空调等散热设备的耗电&#xff0c;间接节省电能。 欢迎私询哦…