Python编程-Python文件处理与自定义异常抛出及警告生成

Python文件处理与自定义异常抛出及警告生成

Python文件操作

打开指定文件

在Python中,open() 函数用于打开文件,并返回一个文件对象,可以用于读取或写入文件内容。open() 函数的基本语法如下:

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

参数说明:

  • file: 文件路径或文件描述符。
  • mode: 打开文件的模式,可以是 'r'(读取,默认)、'w'(写入)、'a'(追加)、'b'(二进制模式)等。具体可以参考下面的说明。
  • buffering: 缓冲区大小,可选参数,默认为 -1,表示使用系统默认的缓冲区大小。
  • encoding: 用于指定文件的编码格式,例如 'utf-8'
  • errors: 当编码或解码错误发生时的处理方式,例如 'ignore' 表示忽略错误。
  • newline: 用于指定换行符,可以是 None'''\n''\r' 等。
  • closefd: 如果为 True(默认),表示关闭文件描述符。在一些特殊情况下,可能需要将其设置为 False
  • opener: 用于自定义打开文件的函数,如果不提供,则使用内置的 open 函数

进行文件读取

read方法

在使用open函数后,我们可以使用对应的read方法来进行文件读取,read方法用于将文件内容全部读取,并且可以指定一个参数来表示要读取的字节数,下面是使用示例:

file_object = open('./123.txt', 'r', encoding='utf-8')
content = file_object.read()
# content = file_object.read(5)
print(content)

输出结果如下:

PS D:\Desktop>  d:; cd 'd:\Desktop'; & 'C:\Users\r123\AppData\Local\Programs\Python\Python311\python.exe' 'c:\Users\r123\.vscode\extensions\ms-python.python-2023.20.0\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher' '1723' '--' 'D:\Desktop\shell.py' 
aaaaa
bbbbb
ccccc
ddddd
eeeee
fffff
PS D:\Desktop>  d:; cd 'd:\Desktop'; & 'C:\Users\r123\AppData\Local\Programs\Python\Python311\python.exe' 'c:\Users\r123\.vscode\extensions\ms-python.python-2023.20.0\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher' '1737' '--' 'D:\Desktop\shell.py' 
aaaaa
PS D:\Desktop> 

readline方法

readline方法用于返回文件的一行,并且每次调用 readline(),它会读取文件的一行内容,并将文件指针移到下一行的开头,并且该方法也提供一个参数,用于指定返回的字节数,如果行的长度大于该字节数,将返回该字节长度,否则返回一行,下面看示例:

file_object = open('./123.txt', 'r', encoding='utf-8')
content = file_object.readline()
print(content)
content = file_object.readline(4)
print(content)

输出结果:

PS D:\Desktop>  d:; cd 'd:\Desktop'; & 'C:\Users\r123\AppData\Local\Programs\Python\Python311\python.exe' 'c:\Users\r123\.vscode\extensions\ms-python.python-2023.20.0\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher' '8343' '--' 'D:\Desktop\shell.py' 
aaaaa

bbbb
PS D:\Desktop> 

readlines方法

readlines() 方法用于一次性读取文件的所有行,并返回一个包含所有行的列表。这个方法也可以接受一个可选的参数,用于指定读取的最大字节数。

基本语法如下:

lines = file.readlines(size)
  • size 是可选参数,表示要读取的字节数。如果省略或为负数,则读取整个文件的所有行。

返回值是一个包含文件所有行的列表,每个元素是文件的一行。如果提供了 size 参数,readlines() 将尝试读取指定数量的字节,然后将其拆分为行。如果没有提供 size 参数,它将读取整个文件的所有行。下面是使用示例:

file_object = open('./123.txt', 'r', encoding='utf-8')
content = file_object.readlines()
print(content)
PS D:\Desktop>  d:; cd 'd:\Desktop'; & 'C:\Users\r123\AppData\Local\Programs\Python\Python311\python.exe' 'c:\Users\r123\.vscode\extensions\ms-python.python-2023.20.0\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher' '12747' '--' 'D:\Desktop\shell.py' 
['aaaaa\n', 'bbbbb\n', 'ccccc\n', 'ddddd\n', 'eeeee\n', 'fffff']
PS D:\Desktop> 

进行文件写入

要进行文件写入,必须在open方法中指定一个可以修改文件的模式,然后使用write方法写入文件。write方法接受一个字符串参数,作为写入文件的内容,下面是简单示例与运行结果:

file_object = open('./123.txt', 'w', encoding='utf-8')
file_object.write('Hello World!')   	# 注意W模式将会覆盖原文件

Python编程-Python文件处理与自定义异常抛出及警告生成_第1张图片

关闭已打开文件

上述的小脚本文件,我们使用完了文件将会由系统回收机制自动回收,所以并未关闭文件,而在一些大型的程序中关闭文件有时是十分必要的,我们可以使用close方法手动关闭文件,如下在文件中写入三段话后关闭文件:

file_object = open('./123.txt', 'w', encoding='utf-8')
file_object.write('Hello World!')
file_object.write('Hello Python!')
file_object.write('Hello Visual Studio Code!')
file_object.close()

自动文件关闭

通常来讲,由于手动关闭文件可能会造成一定问题,如文件提前关闭等,所以我们更建议使用with关键字来处理文件的打开与关闭,下面为简单示例:

with open('./123.txt', 'w', encoding='utf-8') as file_object:
    file_object.write('Hello World!')
    file_object.write('Hello Python!')
    file_object.write('Hello Visual Studio Code!')

注意:使用 with 语句的好处是,即使在发生异常的情况下,它也能确保文件被正确关闭。在离开 with 代码块时,无论正常执行还是发生异常,都会触发关闭操作

Python异常简介

在 Python 中,异常是程序运行过程中可能遇到的错误或异常情况的表示。当发生异常时,Python 会抛出一个异常对象。异常对象是异常类(Exception class)的实例,它包含有关异常的详细信息,如异常的类型、消息等。

以下是 Python 中一些常见的异常类:

异常 描述
BaseException 所有内建异常的基类。
Exception 几乎所有标准异常的基类。
TypeError 当一个操作或函数应用于不适当类型的对象时引发的异常。
ValueError 当一个操作或函数接收到一个正确类型但是不合适的值时引发的异常。
NameError 当访问一个未定义的变量时引发的异常。
ZeroDivisionError 在除法或取模运算的第二个参数为零时引发的异常。
IndexError 尝试访问序列的索引超出范围时引发的异常。
KeyError 在字典中查找一个不存在的键时引发的异常。
FileNotFoundError 尝试打开一个不存在的文件时引发的异常。
IOError 输入/输出操作失败时引发的异常。
SyntaxError 在代码语法错误的情况下引发的异常。
AttributeError 当试图访问对象不存在的属性时引发的异常。
ImportError 在导入模块失败时引发的异常。
RuntimeError 在代码运行时发生的错误,通常是由于逻辑错误引起的。
StopIteration 迭代器没有更多的项时引发的异常。
TypeError 在不同类型之间进行无效操作时引发的异常。

主动抛出异常与捕获

主动抛出异常

if 5 > 0:
    raise Exception("Error throw success")  # 这里构造了一个Exception类的对象抛出(其构造后面细说)

终端手动运行可得到以下结果,由于抛出了错误未处理,编辑器运行时将会报错,从而无法运行:

PS D:\Desktop\Code> python shell.py
Traceback (most recent call last):
  File "D:\Desktop\Code\shell.py", line 2, in <module>
    raise Exception("Error throw success")
Exception: Error throw success
PS D:\Desktop\Code> 

捕捉异常

在编写过程中通常使用 tryexcept 语句来捕获并处理异常,如下除以0的简单示例:

try:
    5/0
except ZeroDivisionError as error:
    print(error)

值得一提的是,在你捕获错误后,仍然可以抛出,然后交由下一层进行捕获,然后不做任何操作:

try:
    try:
        5/0
    except ZeroDivisionError as error:
        raise
except ZeroDivisionError as e:
    pass

自定义异常类

Exception类的构造

在 Python 中,Exception 类是所有标准异常的基类。它提供了一种通用的方式来创建自定义异常。

Exception 类的构造方法定义如下:

class Exception([args])
  • args: 异常的参数,可以是任意类型,任意数量的值,通常是一个描述异常的字符串。

示例:

try:
    if 5 > 0:
        raise Exception("Hello", "Python", " World")
except Exception as error:
    print(error)

运行得到以下结果:

PS D:\Desktop\Code> 
('Hello', 'Python', ' World')
PS D:\Desktop\Code> 

异常子类继承使用

当创建一个继承自 Exception 的新类时,可以选择在构造方法中传递参数,并通过 super().__init__(args) 来调用父类的构造方法。这样做可以在创建异常对象时提供额外的信息(实测也可以不用), 如以下示例:

class KunError(Exception):
    def __init__(self, kun_behavior):
        super().__init__(kun_behavior)
        self.behaviors = kun_behavior
    
    def __str__(self) -> str:
        behavior_str = ''
        for behavior in self.behaviors:
            behavior_str += (behavior + ' ')
        return 'Ikun don\'t ' + behavior_str


if __name__ == "__main__":
    try:
        raise KunError(('sing', 'jump', 'rap', ' play basketball'))
    except KunError as error:
        print(error)

我们在坤的错误这个类中将行为描述传递给了父类Exception,并在脚本运行时进行了抛出与捕获

为何不推荐使用继承BaseException

自定义的异常类应该总是继承自内建的 Exception 类,或者继承自一些本地定义的基类, 而这个基类本身又是继承自 Exception 的。虽然所有的异常也都继承自 BaseException, 但不应该将它作为基类来产生新的异常。BaseException 是预留给系统退出异常的,比 如 KeyboardInterrupt 或者 SystemExit,以及其他应该通知应用程序退出的异常。因此, 捕获这些异常并不适用于它们本来的用途。假设遵循这个约定,从 BaseException 继承 而来的自定义异常将无法捕获,也不能通知应用程序关闭

连续引发异常

在异常处理中,我们有时候需要处理由内部错误引起的其他一系列错误,此时就可以使用raise ... from ...语句来处理,这样既捕获了错误,又可以通过__cause__来复原错误链,即捕获多个错误:

class KunError(Exception):
    def __init__(self, kun_behavior):
        super().__init__(kun_behavior)
        self.behaviors = kun_behavior
    
    def __str__(self) -> str:
        behavior_str = ''
        for behavior in self.behaviors:
            behavior_str += (behavior + ' ')
        return 'Ikun don\'t ' + behavior_str

class KunPlayError(Exception):
    def __init__(self, behavior):
        self.behavior = behavior
    
    def __str__(self) -> str:
        return self.behavior

if __name__ == "__main__":
    try:
        try:
            raise KunPlayError('Stir-fried rice noodles without chicken essence seasoning')
        except KunPlayError as error:
            raise KunError(('sing', 'jump', 'rap', ' play basketball')) from error
    except KunError as e:
        print(e)
        print(e.__cause__)

如上代码,便利用了连续的异常捕获,通过坤的错误,还原异常源头是坤的行为异常,得到运行结果:

PS D:\CodeProjects\VScodeProjects\pythonException>  
Ikun don't sing jump rap  play basketball 
Stir-fried rice noodles without chicken essence seasoning
PS D:\CodeProjects\VScodeProjects\pythonException>

异常处理的推荐写法

try-except-else处理无异常时的行为

try:
    print("Works normally")
except WorkRuningError as e:
    print("要不还是跑路吧 [Doge]")
else:
    print("Why hasn't the earth exploded yet!!!")

try-except-finally处理所有情况下的行为

try:
    print("Works normally")
except WorkRuningError as e:
    print("要不还是跑路吧 [Doge]")
finally:
    while True:
        time.Sleep(1)

自定义警告抛出

在python的自动化测试模块中有warnings类,它的warn方法用来自定义警告抛出,我们在IDE中既可以直接调试,也可以在终端输入如下命令运行:

python -W all 文件名

warn()函数的参数是一条告警信息附带一个告警类别,通常类别为 UserWarning、 DeprecationWarning 、 SyntaxWarning 、 RuntimeWarning 、 ResourceWarning 或 者 FutureWarning 中的一种

-----------《Python Cook book》

如以下测试代码及其运行结果:

import warnings

def warning_func(argument):
    if argument is not None:
        warnings.warn('Hello Wolrd', DeprecationWarning)

warning_func(233)
PS D:\CodeProjects\VScodeProjects\pythonException> python -W all shell.py
D:\CodeProjects\VScodeProjects\pythonException\shell.py:5: DeprecationWarning: Hello Wolrd
  warnings.warn('Hello Wolrd', DeprecationWarning)
PS D:\CodeProjects\VScodeProjects\pythonException>

注意:我们可以在命令行将警告转化为异常,在终端输入以下命令:

python -W error 文件名

得到运行结果:

PS D:\CodeProjects\VScodeProjects\pythonException> python -W error shell.py
Traceback (most recent call last):
  File "D:\CodeProjects\VScodeProjects\pythonException\shell.py", line 7, in <module>
    warning_func(233)
  File "D:\CodeProjects\VScodeProjects\pythonException\shell.py", line 5, in warning_func
    warnings.warn('Hello Wolrd', DeprecationWarning)
DeprecationWarning: Hello Wolrd
PS D:\CodeProjects\VScodeProjects\pythonException>

你可能感兴趣的:(python,开发语言)