一.异常处理机制
经常使用qq的朋友们都知道,QQ不时会让你升级,有心的小伙伴在升级日志里会看见许多已修复了XXX。奇怪,当我们编写程序时发生错误时总会叫停整个程序,而这些软件上出现种种错误,去不影响我们平时的使用,这是为什么?
这一现象的背后就是异常处理机制的功劳
定义
异常处理机制是编程语言或计算机硬件中用于处理软件或信息系统中出现的异常状况的机制。正是在他的帮助下,才能让程序出现部分异常的情况,依旧能够运行。异常处理机制通过合理地运用,可以使程序更好地应对各种异常情况,提高程序的稳定性和可维护性。除此之外,他还有很多看家本领
作用
1.提高程序稳定性。异常处理机制能够捕获并处理程序执行过程中出现的错误或意外情况,避免程序崩溃,从而提高程序的稳定性和可靠性
2简化代码维护:通过分离错误处理与正常业务逻辑,异常处理机制使代码更加清晰、易读,方便程序员编写和维护
3.增强错误处理能力:异常处理机制允许程序员定义自定义异常,并在捕获异常后执行相应的处理逻辑,提供精细和灵活的错误处理机制
4.提升程序健壮性:异常处理机制帮助程序更好地应对未知异常情况,使程序在遇到异常时能够继续执行其他操作或采取补救措施,增强程序的健壮性和容错性。
运用
来让我们了解一下最基础的异常处理,他包含了大多方面,让我们能够清楚了解问题,并解决。
1.1常见错误类型
print(name)
NameError: name 'name' is not definedprint(int('100a'))
ValueError: invalid literal for int() with base 10: '100a'print('hello' + 1234)
TypeError: can only concatenate str (not "int") to strls = [1]
print(ls[10])
IndexError: list index out of rangeif 1:
print("我是真的")
IndentationError: expected an indented block after 'if' statement on line 14s1 = 'hello'
print(s1.name)
AttributeError: 'str' object has no attribute 'name'print(3/0)
ZeroDivisionError: division by zeroimport hahaha
ModuleNotFoundError: No module named 'hahaha'f = open('hahaha.txt', 'r')
FileNotFoundError: [Errno 2] No such file or directory: 'hahaha.txt'
1.2捕获错误的格式
语法:
try:代码1 判断条件
except:代码2 有异常执行
else:代码3 没有异常执行
finally:代码4 不管怎样都会执行
和if类似,try语句可以省略else或添加多个except语句
try:print(name)except Exception as e:print(e)else:pass
Exception也是类,是python内置的,我们在python遇到的所有问题他几乎都可以解决。但是实际的程序编程中,我们会遇到更复杂的问题,需要我们去进行额外的设计。譬如,我就想用函数接受一个列表。我们可以一下面的格式,进行创建自己的错误类
class MyError(BaseException):def __init__(self,msg):self.msg = msgdef __str__(self):return self.msgdef fun_1(ls:list):if not isinstance(ls,list):raise MyError("请输入列表")else:print(ls)
ls_1 = "1,2,3,4,5,6"
try:fun_1(ls_1)
except MyError as e:print(e)
从上文我们可以看出,定义自己的异常类时,要继承异常基类,在捕获异常处添加raise来抛出异常。同时,可以看出自定义函数的作用。
1.提供更好的错误信息,方便查找和调试代码问题。
2.区分不同类型的异常,采取不同处理方式。
3.提供更灵活的异常处理逻辑。
关于除数不能为0的异常处理
class MyException(BaseException):def __init__(self, msg):self.msg = msgdef __str__(self):return self.msgdef div(a, b):if b==0:raise MyException("除数不可以为0")else:return a / btry:print(div(3, 1))
except MyException as e:print(e)
日志的简单应用
在python中,记录日志使用logging库,日志的级别从高到低分别为:
1.CRITICAL:系统崩溃级别的错误,必须立即处理
2.ERROR:运行时的错误,可能导致程序无法正常运行
3.WARNING:警告信息
4.INFO:信息性消息,程序正常运行
5.DEBUG:详细信息,通常在诊断问题时有用
import logging
# 设置日志的打印级别
# logging.basicConfig(level=logging.DEBUG)
logging.critical('这是一个critical信息')
logging.error('这是一个error信息')
logging.warning('这是一个warning信息')
logging.info('这是一个info信息')
logging.debug('这是一个debug信息')
# 向指定的日志文件里去打印日志信息
import logging
# logging.basicConfig(filename='./app.log')
# logging.warning('这是一个warning信息')# logging.basicConfig(filename='./app.log', level=logging.DEBUG, filemode='a',
# format='%(name)s - %(levelname)s - %(message)s')
# logging.warning('这是一个warning信息')# %(name)s 日志记录器的名字
# %(levelname)s 日志级别
# %(asctime)s 时间
# %(message)s 消息本身
二、文件操作
在之前学习Linux操作系统,我们说liunx中一切皆文件。那为什么要将文件作为系统中最根本的部分,文件究竟有什么魅力
文件操作是编程中用于对文件进行读写、管理等操作的过程。
- 文件的重要性:文件是数据持久化保存的重要手段。程序运行时的数据存储在内存中,程序退出后数据会丢失。若要将数据持久化保存,则需使用文件。
- 文件的分类:在程序设计中,文件主要分为程序文件和数据文件。程序文件包括源程序文件、目标文件和可执行程序;数据文件则用于存储程序运行时读写的数据。
- 文件的读写方式:文件的读写方式包括顺序读写和随机读写。顺序读写是按文件的顺序进行读写操作;随机读写则允许在文件的任意位置进行读写。
- 文件操作函数:各种编程语言提供了丰富的文件操作函数,如打开文件、关闭文件、读取文件内容、写入文件内容等,方便程序员进行文件操作12。
文件操作是编程中不可或缺的一部分,掌握文件操作的相关知识对于编写高效、稳定的程序至关重要。
我们知道计算机是不能识别我们所直接使用的自然语言,而使用零一组成的机器语言二进制语言,通过字符串的方法,我们可以了解一下二进制语言长什么样子
s = "交大复旦"print("文本文件:", s)
print("二进制文件:", s.encode())
文件位置
我们知道数据可以存放到文件中,那么文件用存放在什么地方。存放文件的位置我们称之为路径。是根据磁盘的物理空间分配使用。由于磁盘相较现实的纸张过于庞大。为了方便使用,又分为相对路径和绝对路径
# 绝对路径
path = "C:\\Users\\admin\\Desktop\\py_gj\\py_day3"
print(path)# ./表示相对路径
path1 = './day3.3.py'
print(path1)# ../表示上一层路径
path2 = "../py_day2/day2.2.py"
print(path2)
2.文件的操作
1.打开文件open
open(file, [mode='r', buffering=-1, encoding=None])
这是打开文件的俄式
参数:
- file: 必需,文件路径(相对或者绝对路径)
- mode: 可选,文件打开模式,默认为r
- buffering: 可选,设置缓冲
- encoding: 可选,一般使用utf-8
返回值:一个文件对象
mode常用的模式:
打开方式 | 功能 | 文件存在时 | 文件不存在时 |
r | 只读方式打开文件 | 打开 | 报错 |
r+ | 以读写方式打开文件 | 打开 | 报错 |
w | 只写方式打开文件 | 打开(清空之前内容) | 新建 |
w+ | 以读写方式打开文件 | 打开(清空之前内容) | 新建 |
a | 以追加方式打开文件(写) | 打开,保留之前内容 | 新建 |
a+ | 以读写方式打开文件 | 打开,保留之前内容 | 新建 |
mode参数还可以指定以什么样的编码方式读写文本,默认情况下open是以文本形式打开文件的,比如上面的四种mode模式。
当我们需要以"字节[二进制]"形式读写文件时,只需要在mode参数的后面加 b 就可以了。
- rb 以二进制形式打开一个文件,只读
- wb 以二进制形式打开一个文件,只写
- wb+ 以二进制形式打开一个文件,读写
f = open("./111.txt",mode='r+',encoding='utf-8')
data_read = f.read()
print(data_read)
f.close()
读取文件
- 我们在同级目录下创建一个名为111的txt文本文件,同时创建一个test.py文件,通过代码去读取其中的内容。
- 我们在111.txt中写入两行内容: Life is short, You need Python 人生苦短,我用python
- 然后在test.py中写入读取代码
f = open("./111.txt",mode='r+',encoding='utf-8')
data_read = f.read()
print(data_read)
f.close()
f.close()方与open对应,是为关闭文件并保存
但是我们难免会遭遇异常在我们还未指向close()程序就已经结束了。为此,我们使用with辅助操作
除了read()之外,我们还有readline与readlines方法
with open('./111.txt',mode='r+') as f:for i in range(4):print(f.readline())#print(f.readlines())
在实践中,我发现readline返回字符串与readlines 返回字符串列表
是不断遍历文件,当执行到最后一行,便无法执行
写操作write
写分为重写W与添加A
s ="1234567890qwerty"
with open('./111.txt',mode='a+') as f:for i in range(4):f.write(s)
with open('./111.txt',mode='r+') as f:print(f.read())
s ="1234567890qwerty"
with open('./111.txt',mode='w+') as f:for i in range(4):f.write(s)
with open('./111.txt',mode='r+') as f:print(f.read())
指针的操作
f.tell()
功能:返回文件的当前位置,即文件指针当前位置fileObject.seek(offset[, whence])
功能:将文件内部光标定位到指定的位置
参数:offset:开始的偏移量,也就是代表需要移动偏移的字节数whence:可选,默认值为 0,0代表从文件开头开始算起1代表从当前位置开始算起2代表从文件末尾算起
eg:
f.seek(p,0) 移动到文件第p个字节处,绝对位置f.seek(p,1) 移动到相对于当前位置之后的p个字节f.seek(p,2) 移动到相对文章尾之后的p个字节f.seek(0,0) 移动到文件开头
s ="1"
with open('./111.txt',mode='w+') as f:for i in range(4):f.write(s)
with open('./111.txt',mode='r+') as f:print(f.tell())print(f.read())print(f.tell())