04.异常文件处理与文件读取学习笔记

异常文件处理学习笔记

1.什么是异常:

在python中的异常其实一个类,如NameErrorSyntaxErrorTypeErrorValueError,它们都继承了Exception基类。

例如,在pycharm中直接输入以下代码

print(a)

返回结果为:

NameError: name 'a' is not defined

2.try/except语句:

try/except语句用于处理程序运行过程中可能遇到的异常或错误。基本语法如下:

try:
    # 尝试执行的代码块
except ExceptionType:
    # 当尝试执行的代码块出现特定类型的异常时,执行的代码块

具体步骤如下:

  1. try:定义了一个代码块,前面的代码块在Python尝试执行,可能会遇到错误或异常。
  2. except:定义了另一个代码块,这个代码块指定了当try语句块中出现指定类型的异常时要执行什么操作。你可以指定捕获特定类型的异常,例如except ValueError:就是只捕获ValueError类型的异常。如果不指定类型,则默认捕获所有类型的异常。

如果在try代码块中出现了异常,Python会停止执行try代码块的剩余部分,并跳转到except代码块。如果try代码块没有出现异常,则会跳过except代码块的执行。

try:
    x = 1 / 0  # 这里会出现ZeroDivisionError
except ZeroDivisionError:
    print("不能除以 0!")

除了try/except,Python还有elsefinally语句块,可以与try/except一起使用,如try/except/else, try/except/finallytry/except/else/finally。其中:

  • else:定义了当try代码块成功没有出现异常时要执行的代码块。

  • finally:无论try代码块是否出现异常,finally后的代码块总是会被执行。这通常用于释放资源,如文件或网络连接。

    例如:

try:
    print(9 / 3)
except Exception as e:
    print('程序异常')
else:
    print('如果执行的代码没有发生异常则执行else中的语句')
finally:
    print('无论代码是否发生异常都必须执行当前语句')

输出结果为:

3.0
如果执行的代码没有发生异常则执行else中的语句
无论代码是否发生异常都必须执行当前语句

3.自定义异常:

示例1:

class MyCustomException(Exception):
    def __init__(self, message):
        self.message = message
    def __str__(self):
        return self.message

try:
    raise MyCustomException("我的自定义异常")
except MyCustomException as e:
    print(e)

在上述代码中:

  1. 我们首先定义了一个名为MyCustomException的类,这个类继承自内置类Exception(一定要写Exception!)。在这个类中,我们定义了类的初始化方法__init__和字符串方法__str__
  2. 在初始化方法__init__中,我们接收一个参数message并将其设置为实例的属性。也就是说,每当我们创建一个MyCustomException的实例时,都需要提供一个参数,这个参数就是异常的具体信息。
  3. __str__方法中,我们返回了异常信息。这个方法在我们打印异常信息时会被调用,返回的就是代表这个异常的字符串。
  4. try/except代码块中,我们尝试引发一个MyCustomException,并且提供了具体的异常信息。当这个异常被引发时,except代码块会捕获这个异常,并打印出异常信息。

输出结果为:

我的自定义异常

示例2:

class Loginerror(Exception):
    def __str__(self):
        return '用户名或密码错误'

name = input('Name')
password = input('Password')

localname = 'jasons'
localpassword  = '123456'

try:
    if name!= localname or password != localpassword:
        raise Loginerror

except Loginerror as e:
    print('程序异常:',e)

当我们输入不对的用户名或者密码时结果显示:

Namejasons
Password234
程序异常: 用户名或密码错误

正确时不返回任何结果。

首先,定义了一个名为Loginerror的自定义异常类,这个类继承自Python的Exception类。在这个类中重写了__str__方法,当这个异常被抛出并转化为字符串时,将返回’用户名或密码错误’。 然后,程序会依次提示用户输入用户名(Name)和密码(Password),并将这两个输入存入name和password两个变量中。 定义了两个变量localname和localpassword,分别赋值为’jasons’和’123456’,代表预设正确的用户名和密码。 下面是一个try/except异常处理结构。在try代码块中,程序检查用户输入的name和password是否与预设的正确用户名和密码(即localname和localpassword)相符。如果不符,就抛出Loginerror异常。 在except代码块中,程序捕获到Loginerror异常,并将异常信息赋值给变量e,然后打印出’程序异常:‘,后面跟着异常信息(即’用户名或密码错误’)。 所以,这个代码的主要功能是检查用户输入的用户名和密码是否正确,如果不正确则抛出相应的异常并打印出异常信息。

4.文件的读写:

1.路径:

在计算机文件系统中,路径是用来定位文件或目录的一种方式,通常可以分为绝对路径和相对路径:

  1. 绝对路径:从根目录开始全路径形式表示的文件路径。绝对路径在文件系统的任何地方都唯一确定一个文件或目录。例如,在UNIX或Linux系统中,绝对路径可能像这样:/home/user/docs/file.txt。在Windows系统中,绝对路径可能像这样:C:\Users\user\documents\file.txt

  2. 相对路径:相对于某个基准目录的路径。相对路径取决于当前的工作目录(在命令行中,或者在代码中当你试图打开一个文件)。例如,如果当前的工作目录是/home/user/docs,那么相对路径./file.txt将指向/home/user/docs/file.txt

    相对路径中,.表示当前目录,..表示上一级目录。例如,对于当前目录/home/user/docs./file.txt表示/home/user/docs/file.txt../file.txt表示/home/user/file.txt

2. open()函数:

在 Python 中,open() 是一个内置函数,用于打开一个文件,并返回一个文件对象。这个函数的语法如下:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

这里是各个参数的含义:

  • file:必需,文件路径(相对或者绝对路径)。
  • mode:可选,文件打开模式。默认是 'r' 表示读取模式。其他常见模式包括 'w' 写入模式,'a' 追加模式,'b' 二进制模式等。模式可以组合使用,比如 'rb' 表示以二进制格式打开一个文件用于只读,'w+' 表示打开一个文件用于读写。
  • buffering:可选,用于设置缓冲策略。默认值为 -1,表示使用系统默认的缓冲策略。
  • encoding:可选,用于设置文件的编码格式。例如: 'utf8''gbk' 等。
  • errors:可选,如果 encoding 和 decoding 异常,该参数定义该如何处理。默认值为 'strict',表示抛出一个 UnicodeError 的异常。其他选项包括 'ignore''replace''xmlcharrefreplace''backslashreplace' 和任何其他处理 UnicodeError 的方法的名称。
  • newline:可选,用于确定如何识别换行符。
3.文件的读取与写入:
1.读取文件:

使用 'r' 模式打开文件进行读取。read() 方法可以读取整个文件的内容,或者给定数量的字符。以下是一个简单的例子:

with open('file.txt', 'r') as f:
    content = f.read()
    print(content)

readline()方法:

readline() :这个方法每次读出来的是一个完整的行(包括换行符)。当读取到文件最后时,返回空字符串。

    with open('file.txt', 'r') as f:
        line = f.readline()
        while line:
            print(line, end='')
            line = f.readline()
这段代码,每次读取一行,并打印,直到文件末尾。

readlines()方法:

readlines() :这个方法返回一个列表,其中每一个元素都是文件中的一行,包括换行符。

    with open('file.txt', 'r') as f:
        lines = f.readlines()
        for line in lines:
            print(line, end='')
这段代码,将文件的每一行作为一个列表元素,并打印这些行。
2.写入文件:

使用 'w' 模式打开文件进行写入。如果文件已存在,'w' 模式会覆盖原有内容;如果文件不存在,将创建一个新文件。

write() 方法可以将字符串写入文件:

with open('./测试文件.txt', 'w') as f:
    f.write('Hello, World!')

在这段代码中,我们首先以 “w” 模式打开 “file.txt” 文件,然后使用 write 方法将字符串 ‘Hello, World!’ 写入文件。

writelines()方法:

Python中的writelines()方法是文件对象的一个方法,它可以一次性向文件写入一个字符串列表。

lines = ['Hello, world!\n', 'Welcome to Python programming.\n']

with open('file.txt', 'w') as f:
    f.writelines(lines)

这段代码首先定义了一个字符串列表lines,然后用'w'模式打开一个名为'file.txt'的文件('w'表示如果文件不存在则创建文件,如果文件存在则清空文件内容),并使用writelines()方法将字符串列表lines写入该文件。这将会导致文件中的内容是:

Hello, world!
Welcome to Python programming.

注意到每个字符串后面都添加了一个换行字符\n,这是为了在文件中让每个字符串独占一行。如果不添加换行符,那么所有的字符串将会在文件中连续排列,之间没有任何分隔字符。

需要注意的是,writelines()并不会自动为列表中的每一项添加换行符,所以如果需要的话,需要我们手动在每一项字符串后面添加\n

3.追加写入文件:

如果你希望在文件内容末尾追加内容,而不是覆盖原有内容,可以使用 'a' 模式:

file_path = './测试文件.txt'
file_obj = open(file_path, mode='a', encoding='utf-8')
file_obj.write('\n双双胖三斤...')
4,mode二进制模式:

在Python中,open()函数的mode参数用于指定打开文件的方式,包括读取、写入和追加,以及文本和二进制格式。这里,“二进制模式”的含义是指以字节形式读取、写入或追加该文件,而不是通常的字符形式。

以下是一些常见的二进制模式:

  • 'rb':以二进制格式打开文档进行读取。这种模式下,你可以读取所有类型的文件,包括图像、视频等。
  • 'wb':以二进制格式打开文档进行写入。如果该文件已经存在,其现有内容将被清除;否则,新文件将被创建。
  • 'ab':以二进制格式打开文档进行追加。这种模式下,你的新数据将被添加至已有文件的末尾。如果文件不存在,它将会被创建。

与字符模式(如'r''w''a')相比,二进制模式可以处理各种类型的文件,而不仅仅是文本文件。例如,如果你想读取或写入一张图像或一个音频文件,你就需要用到二进制模式,因为这些文件不能被视为简单的文本。

4.自定义类完成文件读写:
class MyOpenFile:
    def __init__(self, file_path):
        self.file_obj = None
        self.file_path = file_path

    def __enter__(self):
        print('即将创建文件对象...')
        self.file_obj = open(self.file_path, 'r')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('即将释放文件对象...')
        self.file_obj.close()

    def my_read(self):
        print(self.file_obj.read())


with MyOpenFile('./测试文件.txt') as file_obj:
    file_obj.my_read()

这段代码主要实现了Python中的上下文管理协议,通过重载__enter____exit__方法使得MyOpenFile类支持with语句。

  1. __init__方法是类的构造方法,在创建MyOpenFile类的新实例时被自动调用。方法接受一个参数file_path(文件路径),并将其存储在实例变量self.file_path中。实例变量self.file_obj被初始化为None
  2. __enter__方法在with语句的开始处被自动调用。方法打印一条消息“即将创建文件对象…”,然后打开self.file_path指定的文件,并将打开的文件对象存储在self.file_obj中。最后,返回self,使得在with语句中可以通过名称file_obj访问这个类的实例。
  3. my_read方法读取self.file_obj指向文件的内容,并打印出来。
  4. __exit__方法在with语句的结束处被自动调用,无论with语句正常结束还是异常结束。方法打印一条消息“即将释放文件对象…”,然后关闭self.file_obj指向的文件。
  5. with语句内,我们通过file_obj.my_read()调用了my_read方法,打印出文件的内容。
  6. with语句结束时,__exit__方法自动被调用,文件被正确关闭。

这个类的主要用途是提供一种便捷的方式来操作文件。使用这个类,我们无需手动打开、关闭文件,无论在文件操作的过程中是否发生异常,文件都会在with语句结束时被正确关闭。(如果一个类没有定义__enter____exit__这两个方法,那么这个类的实例不能在with语句中使用。)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值