异常处理和调试

1、异常捕获

编程语言在程序运行的时候,难免会发生错误,特别是程序在调试的时候,如果程序在运行过程中发生错误,将会导致程序崩溃退出,但是很多时候我们并不希望程序退出,我们可能只是希望程序给我返回一个错误信息,然后程序能够继续运行,这时,我们就可以使用python的异常处理机制。Python中和异常相关的关键字有五个,分别是tryexceptelsefinallyraise

try:
	print(a)
except NameError: 
	print("出现名字的异常了")
else:
	print('没有异常时执行的代码')
finally:
	print("结束")

在python中,将需要检测的语句放在try代码块中,try后可以跟多个except代码块来捕获不同的异常并进行处理,else代码块是检测的代码不发生异常时执行的语句,不管是否发生异常finally都会执行。上面的代码由于a没有定义,产生了NameError异常,我们在except捕获这个异常并且执行相关语句。

2、内置异常类型

python内置了大量的异常类型,下面列一下部分异常

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
      |    +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

Python所有的异常都是BaseException的子类型,子类型中最常用的是Exception类型,他是常规异常类型的父类型,也就是说,我们程序运行碰到的大部分异常都是它的子类型。

3、自定义异常

当内置的异常类型不满足程序要求时,我们也可以自定义异常来满足我们的要求,自定义异常需要用到raise关键字,并且自定义异常也应该继承于Exception或其子类型。

class PwLen(Exception):
	'''自定义异常类型'''
	pass

def test(number):
	if number<10:
		raise PwLen('number不能小于10')  #触发异常
	return number

try:
	t=test(9)
except PwLen as p:
	print(p)  #打印异常
else:
	print(t)

上面的例子是简单的自定义异常,我们还可以在自定义异常类中做更多的操作以满足不同的异常。

4、调试

程序编写过程中,经常需要进行调试,已保证能得到我们想要的结果,出现bug时,有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是正确的,哪些变量的值是错误的,因此我们需要有调试的手段来修复bug。

第一种调试的方法很简单也很粗暴,就是直接用print把可能出现的错误的值打印出来看看是不是正常,很多人都是直接用这种方法,包括我也是,在写脚本时经常用到print来打印变量,但是这种调试方法不好的地方就是一旦写print的地方太多的话,很混乱,并且不能一眼就看出bug所在,需要我们做判断。

第二种方法就是使用断言(assert),凡是用print来辅助查看的地方,都可以用断言(assert)来替代。

def N(n):
	assert n!=0,'n不能为0'
	print(n)

N(0) #这里会直接导致程序崩溃,并打印出“n不能为0”

assert判断某个表达式的值时,如果结果为True,则程序继续执行,如果结果为False,则报AssertionError错误。在编写程序的时候,养成习惯,尽量使用断言去调试,而不是选择print。在运行程序时,可以加-O选项来忽略assert语句。

第三种方法是通过logging模块来进行调试,和assert相比,这种方法不会抛出错误,而是输入到文件。

import logging
import os

#获取当前文件路径,__file__表示当前文件的绝对路径
current_work_dir = os.path.dirname(__file__)

#更改日志输出的格式
LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
#设置日志时间格式
DATE_FORMAT = "%m/%d/%Y %H:%M:%S %p"

logging.basicConfig(level=logging.DEBUG,filename=f'{current_work_dir}\log.txt',format=LOG_FORMAT,datefmt=DATE_FORMAT)

logging.log(logging.DEBUG, "This is a debug log.")
logging.log(logging.INFO, "This is a info log.")
logging.log(logging.WARNING, "This is a warning log.")
logging.log(logging.ERROR, "This is a error log.")
logging.log(logging.CRITICAL, "This is a critical log.")

'''
04/22/2022 10:33:25 AM - DEBUG - This is a debug log.
04/22/2022 10:33:25 AM - INFO - This is a info log.
04/22/2022 10:33:25 AM - WARNING - This is a warning log.
04/22/2022 10:33:25 AM - ERROR - This is a error log.
04/22/2022 10:33:25 AM - CRITICAL - This is a critical log.
'''

logging有5中日志级别,默认是WARNING级别,因此logging.basicConfig不指定级别的情况下,DEBUG和INFO级别的信息是不输出的,如果想要输出所有级别的日志,需要将level设置为DEBUG。在编写复杂的程序时,日志信息是不可缺少的。
我的博客:https://blog.z7sz.top

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xingyuzhongxuan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值