详解Python异常处理、文件读写

作者 | pythonic生物人

详细梳理python异常处理方法:try/except/else/finally/raise/assert

详细梳理python文件读写:open/write

目录

1.异常处理

处理单个异常:try/except

多个异常一种方式处理:元组包含多个异常类型

多个异常各自特异处理:多个except语句

处理所有异常:Exception 捕获所有异常

脚本执行之后做清理工作:finally

没有触发异常的时候执行一些任务:try/else

主动触发某个异常类型:raise

满足某个条件触发异常:assert

python3中内置标准异常类型

2.Python中文件读写

python3中open函数

一次读取整个文件

逐行读取文件

覆盖已有内容写入文件

追加内容写入文件

1.异常处理

异常处理不建议随便乱用,过度使用使得代码可读性变差;在异常无法预知的情况下建议使用异常处理,其他异常尽量解决。

处理单个异常:try/except

可能触发异常的代码会放到try语句块里,处理异常的代码放在except语句块里。

try:#try代码块中任何一行代码报错,该行代码后面的语句就不会执行,抛出错误类型。

    file = open(test, rb)except IOError as e:

#IOError为异常类型,如果try中抛出的错误正好是该异常类型,执行except中代码处理掉异常,程序继续执行,否则终止程序。

    print(An IOError occurred. {}.format(e.args[-1]))#处理异常的代码 。

An IOError occurred. No such file or directory

多个异常一种方式处理:元组包含多个异常类型

把所有可能发生的异常类型存储到一个元组中。

try:    file = open(test, rb)

except (IOError, EOFError) as e:#多个异常类型存储在(IOError, EOFError)元组中

    print("An error occurred. {}".format(e.args[-1]))

An error occurred. No such file or directory

多个异常各自特异处理:多个except语句

对每个异常类型使用一个except语句块处理

try:    file = open(test, rb)

except EOFError as e:#该except处理EOFError类型异常

    print("An EOF error occurred.")

except IOError as e:#该except处理IOFError类型异常

    print("An error occurred.")

An error occurred.

处理所有异常:Exception 捕获所有异常

try:    file = open(test, rb)

except Exception as e:#Exception捕获所有的异常类型,保存到args的元组中。

    print(All exceptions {}.format(e.args))

All exceptions (2, No such file or directory)

脚本执行之后做清理工作:finally

finally中的代码块不管异常是否被触发都会被执行,常用来在脚本执行之后做清理工作。

try:    file = open(test, rb)except IOError as e:    print(An IOError occurred. {}.format(e.args[-1]))

finally:#该语句块一定会执行,无论try中是否触发代码,无论except中是否处理异常。

    print("This would be printed whether or not an exception occurred!")

An IOError occurred. No such file or directoryThis would be printed whether or not an exception occurred!

没有触发异常的时候执行一些任务:try/else

try代码块中异常没被触发,执行else语句块。

try:    print(I am sure no exception is going to occur!)except Exception:    print(exception)

else:#try语句块没有触发异常时运行;该代码块中异常不会被捕获。

    print(This would only run if no exception occurs. And an error here would NOT be caught.)finally:    print(This would be printed in every case.)I am sure no exception is going to occur!

This would only run if no exception occurs. And an error here would NOT be caught.

This would be printed in every case.

主动触发某个异常类型:raise

try:

raise IOError(一个主动触发的异常类型)#这个异常主动触发

except Exception as e:    print(e.args)

(一个主动触发的异常类型,)

满足某个条件触发异常:assert

try:

assertFalse,"前面bool判断为False是触发异常"

except Exception as e:    print(e.args)

(前面bool判断为False是触发异常,)

python3中内置标准异常类型

只见过几个,如ZeroDivisionError、ImportError、IndexError、KeyError、TypeError、ValueError、SystemError等少数几个。python3中内置的异常类型及各异常之间的继承关系,各异常类型的触发原因见下表:

python内置标准异常类型

及继承关系(python3.8.3)

触发异常原因

BaseException

所有内置异常的基类。

 +-- SystemExit

sys.exit()函数引发。

 +-- KeyboardInterrupt

当用户按下中断键(通常为Control-C或Delete)时将被引发。

 +-- GeneratorExit

当一个生成器generator或coroutine被关闭时将被引发

 +-- Exception

所有内置的非系统退出类异常和自定义异常都派生自此类。

      +-- StopIteration

内置函数next()和迭代器iterator的__next__()方法所引发。

      +-- StopAsyncIteration

由一个asynchronous iterator对象的__anext__()方法来引发以停止迭代操作。

      +-- ArithmeticError

各种算术类错误而引发的内置异常

      |    +-- FloatingPointError

目前未被使用,呵呵~。

      |    +-- OverflowError

当算术运算的结果大到无法表示时将被引发。

      |    +-- ZeroDivisionError

当除法或取余运算的分母为零时将被引发。

      +-- AssertionError

当assert(bool判断触发异常)语句失败时将被引发。

      +-- AttributeError

当属性引用或赋值失败时将被引发(经常见)。

      +-- BufferError

当与缓冲区相关的操作无法执行时将被引发。

      +-- EOFError

当input()函数未读取任何数据即达到文件结束条件(EOF)时将被引发。

      +-- ImportError

导入模块时引发,当import加载模块和from/import中的"from list"存在无法找到的名称时被引发。

      |    +-- ModuleNotFoundError

一个模块无法被定位时将由import引发,当在sys.modules中找到None时也会被引发。

      +-- LookupError

IndexError,KeyError异常引发及codecs.lookup()直接引发。

      |    +-- IndexError

超过序列类数据结构(list,str等)索引范围时将被引发。

      |    +-- KeyError

映射类数据结构(dict)中找不到键时将被引发。

      +-- MemoryError

当一个操作耗尽内存但情况仍可(通过删除一些对象)进行挽救时将被引发。

      +-- NameError

当某个局部或全局名称未找到时将被引发。

      |    +-- UnboundLocalError

当在函数或方法中对某个局部变量进行引用,但该变量并未绑定任何值时将被引发。

      +-- OSError

根据系统错误代码被引发。

      |    +-- BlockingIOError

当一个操作会被某个设置为非阻塞操作的对象(例如套接字)所阻塞时将被引发。

      |    +-- ChildProcessError

当一个子进程上的操作失败时将被引发。对应于errno ECHILD。

      |    +-- ConnectionError

与连接相关异常的基类。

      |    |    +-- BrokenPipeError

当试图写入另一端已被关闭的管道,或是试图写入已关闭写入的套接字时将被引发。对应于errno EPIPE和ESHUTDOWN。

      |    |    +-- ConnectionAbortedError

当连接尝试被对端中止时将被引发。对应于errno ECONNABORTED。

      |    |    +-- ConnectionRefusedError

当连接尝试被对端拒绝时将被引发。对应于errno ECONNREFUSED。

      |    |    +-- ConnectionResetError

当连接被对端重置时将被引发。对应于errno ECONNRESET。

      |    +-- FileExistsError

当试图创建一个已存在的文件或目录时将被引发。对应于 errno EEXIST。

      |    +-- FileNotFoundError

当所请求的文件或目录不存在时将被引发。对应于errno ENOENT。

      |    +-- InterruptedError

当系统调用被输入信号中断时将被引发。对应于errno EINTR。

      |    +-- IsADirectoryError

当请求对一个目录执行文件操作(例如os.remove())将被引发。对应于errno EISDIR。

      |    +-- NotADirectoryError

当请求对一个非目录对象执行目录操作(例如os.listdir())时将被引发。对应于errno ENOTDIR。

      |    +-- PermissionError

当在没有足够操作权限的情况下试图执行某个操作时将被引发——例如缺少文件系统权限。对应于errno EACCES和EPERM。

      |    +-- ProcessLookupError

当给定的进程不存在时将被引发。对应于errno ESRCH。

      |    +-- TimeoutError

当一个系统函数发生系统级超时的情况下将被引发。对应于errno ETIMEDOUT。

      +-- ReferenceError

此异常将在使用weakref.proxy()函数所创建的弱引用来访问该引用的某个已被作为垃圾回收的属性时被引发。

      +-- RuntimeError

当检测到一个不归属于任何其他类别的错误时将被引发。关联的值是一个指明究竟发生了什么问题的字符串。

      |    +-- NotImplementedError

在用户自定义的基类中,抽象方法应当在其要求所派生类重载该方法,或是在其要求所开发的类提示具体实现尚待添加时引发此异常。

      |    +-- RecursionError

解释器检测发现超过最大递归深度被引发。

      +-- SyntaxError

当解析器遇到语法错误时将被引发。

      |    +-- IndentationError

与不正确的缩进相关的语法错误的基类。

      |         +-- TabError

当缩进包含对制表符和空格符不一致的使用时将被引发。

      +-- SystemError

当解释器发现内部错误,但情况看起来尚未严重到要放弃所有希望时将被引发。

      +-- TypeError

当一个操作或函数被应用于类型不适当的对象时将被引发。

      +-- ValueError

当操作或函数接收到具有正确类型但值不适合的参数,并且情况不能用更精确的异常例如IndexError来描述时将被引发。

      |    +-- UnicodeError

当发生与Unicode相关的编码或解码错误时将被引发。

      |         +-- UnicodeDecodeError

当在"解码过程"中发生与Unicode相关的错误时将被引发。

      |         +-- UnicodeEncodeError

当在"编码过程"中发生与Unicode相关的错误时将被引发。

      |         +-- UnicodeTranslateError

在"转写过程"中发生与Unicode相关的错误时将被引发。

      +-- Warning

警告类别的基类。

           +-- DeprecationWarning

如果所发出的警告是针对其他Python开发者的,则以此作为与已弃用特性相关警告的基类。

           +-- PendingDeprecationWarning

对于已过时并预计在未来弃用,但目前尚未弃用的特性相关警告的基类。

           +-- RuntimeWarning

与模糊的运行时行为相关的警告的基类。

           +-- SyntaxWarning

与模糊的语法相关的警告的基类。

           +-- UserWarning

用户代码所产生警告的基类。

           +-- FutureWarning

如果所发出的警告是针对以Python所编写应用的最终用户的,则以此作为与已弃用特性相关警告的基类。

           +-- ImportWarning

与在模块导入中可能的错误相关的警告的基类。

           +-- UnicodeWarning

与Unicode相关的警告的基类。

           +-- BytesWarning

与bytes和bytearray相关的警告的基类。

           +-- ResourceWarning

与资源使用相关的警告的基类。会被默认的警告过滤器忽略。

2.Python中文件读写

python3中open函数

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

file,被打开的文件;

mode,打开模式,默认为‘r’即读取模式;

详细如下表:

字符

含义

r

读取(默认)

w

覆盖写入,如果文件中已有内容,则覆盖

x

排它性创建,如果文件已存在则失败

a

追加写入,如果文件已有内容,则在末尾追加

b

二进制模式

t

文本模式(默认)

+

更新磁盘文件(读取并写入)

buffering,设置缓冲;encoding,一般使用utf8,没有指定,则根据平台来决定使用的编码;......(后面的我很少用)

一次读取整个文件

file = ./test.txt#指定文件路径及文件

with open(file,encoding=gbk) as f:#关键字with 在不再需要访问文件后自动将其关闭,所以不需要close关闭文件。

    contents = f.read()#方法read()读取文件的全部内容,以字符串的形式存储在变量contents中    print(contents)

逐行读取文件

file = ./test.txt

with open(file) as f:

for line in f:#使用for循环

        line = line.strip()#strip去掉每行末尾换行符        print(line)

覆盖已有内容写入文件

file = ./test.txt

with open(file,encoding=gbk) as f:

    contents = f.read()

with open("./test1.txt", w) as f:#w覆盖已有文件内容

    f.write(contents)

#test1.txt中内容

追加内容写入文件

file = ./test.txt

with open(file,encoding=gbk) as f:

    contents = f.read()

with open("./test1.txt", w) as f:#w覆盖已有文件内容

    f.write(contents)

test1.txt中内容,末尾追加了一行,不覆盖已有内容。