第二章 程序调试与异常处理

1. 【应用断言调试程序】assent语句

语法参考

assert的中文意思是断言,它一般用于对程序某个时刻必须满足的条件进行验证。assert语句的基本语法如下:

assert expression [,reason]

参数说明:

  • expression:条件表达式,如果该表达式的值为真时,什么都不做,如果为假时,则抛出AssertionError异常。

  • reason:可选参数,用于对判断条件进行描述,为了让他人更好地知道出现了什么问题。

锦囊1 使用断言调试程序

要求输入一个数字,然后使用assert语句对输入的空值抛出异常,代码如下:

number = input('请输入一个数字:')
assert number != '' ,'不能输入空值!'   		# 当值为空时通过断言抛出异常
print('您输入了:',number)

锦囊2 在除法运算中使用断言调试程序

定义执行除法运算的division()函数,并且在该函数中使用assert断言调试程序,代码如下:

def division():
    num1 = int(input('请输入被除数:')) 	# 用户输入提示,并记录
    num2 = int(input('请输入除数:'))
    assert num2 != 0, '除数不能为0'  		# 应用断言调试
    result = num1//num2 				# 执行除法运算
    print(result)

if __name__ == '__main__':
        division()  					# 调用函数

锦囊3 应用断言和异常处理语句处理异常

定义执行除法运算的division()函数,并且在该函数中使用assert断言和异常处理语句try…except处理异常,代码如下:

def division():
    num1 = int(input('请输入被除数:')) 			# 用户输入提示,并记录
    num2 = int(input('请输入除数:'))
    assert num2 != 0, '除数不能为0'     			# 应用断言调试
    result = num1//num2                 		# 执行除法运算
    print(result)

if __name__ == '__main__':
    try:
        division()                             	# 调用函数
    except AssertionError as e:                	# 处理AssertionError异常
        print('\n输入有误:',e)

说明:assert语句只在调试阶段有效。我们可以通过在执行python命令时加入-O(大写)参数来关闭assert语句。

2. 【抛出异常】raise语句

语法参考

如果某个函数或方法可能会产生异常,但不想在当前函数或方法中处理这个异常,则可以使用raise语句在函数或方法中抛出异常。raise语句的基本格式如下:

raise [ExceptionName[(reason)]]

其中,ExceptionName[(reason)]为可选参数,用于指定抛出的异常名称,以及异常信息的相关描述。如果省略,就会把当前的错误原样抛出。

说明:ExceptionName(reason)参数中的(reason)也可以省略,如果省略,则在抛出异常时,不附带任何描述信息。

锦囊1 使用raise语句抛出异常并处理

在执行除法运算时,在division()函数中实现,当除数为0时,应用raise语句抛出一个ValueError异常,并且在最后一行语句的下方添加except语句处理ValueError异常,代码如下:

def division():

    num1 = int(input('请输入被除数:')) 		# 用户输入提示,并记录
    num2 = int(input('请输入除数:'))

    if num2 == 0:
        raise ValueError('除数不能为0')
    result = num1//num2 					# 执行除法运算
    print(result)

if __name__ == '__main__':
    try:  									# 捕获异常
        division()  						# 调用函数
    except ValueError as e:  				# 处理ValueError异常
        print('输入错误:', e)  				# 输出错误原因

锦囊2 使用raise语句针对不同情况抛出不同异常

对登录信息进行分项验证,哪项不合法,就使用raise语句抛出ValueError异常,并且应用try…except语句处理异常,代码如下:

try:
    username = input('请输入用户名(不超过16个字符):')
    pwd = input('请输入密码(只能由字母和数字组成):')

    if len(username) >16:  													# 如果用户超过16个字符
        raise ValueError('用户名输入不合法,不能超过16个字符!')  				# 抛出ValueError异常
    if not pwd.isalnum():
        raise ValueError('密码输入不合法,不能包括除了数字和字母以外的字符!')		# 抛出ValueError异常

except ValueError as e:
    print(e)

3. 【捕获异常】try…except语句

语法参考

try…except语句用于捕获并处理异常。在使用时,把可能产生异常的代码放在try语句块中,把处理结果放在except语句块中,这样,当try语句块中的代码出现错误,就会执行except语句块中的代码,如果try语句块中的代码没有错误,那么except语句块将不会执行。具体的语法格式如下:

try:
    block1
except [ExceptionName [as alias]]:
    block2

参数说明:

  • block1:表示可能出现错误的代码块。

  • ExceptionName [as alias]:可选参数,用于指定要捕获的异常。其中,ExceptionName表示要捕获的异常名称,如果在其右侧加上as alias则表示为当前的异常指定一个别名,通过该别名,可以记录异常的具体内容。

说明:在使用try…except语句捕获异常时,如果在except后面不指定异常名称,则表示捕获全部异常。

  • block2:表示进行异常处理的代码块。在这里可以输出固定的提示信息,也可以通过别名输出异常的具体内容。

说明:使用try…except语句捕获异常后,当程序出错时,输出错误信息后,程序会继续执行。

锦囊1 一次捕获一种异常

在执行除法运算时,对可能出现的异常进行处理,代码如下:

def division():
    num1 = int(input('请输入被除数:'))  		# 用户输入提示,并记录
    num2 = int(input('请输入除数:'))
    result = num1//num2                  	# 执行除法运算
    print(result)

if __name__ == '__main__':
    try:                                  	# 捕获异常
       division()                         	# 调用分苹果的函数
    except ZeroDivisionError:           	# 处理异常
       print('输入错误:除数不能为0')    		# 输出错误原因

锦囊2 一次捕获多种异常

在进行除法运算时,不仅可能出现除数为0的异常,还可能出现输入的值错误的情况,下面将应用一个try…except语句捕获可能出现的两种异常,代码如下:

def division():
    num1 = int(input('请输入被除数:')) 			# 用户输入提示,并记录
    num2 = int(input('请输入除数:'))
    result = num1//num2 						# 执行除法运算
    print(result)

if __name__ == '__main__':
    try:  										# 捕获异常
        division()  							# 调用函数
    except (ZeroDivisionError,ValueError):  	# 处理异常
        print('您的输入有误!')

说明:如果还需要捕获更多种异常,可以在ValueError的后面继续添加异常名称,并且使用英文半角的逗号分隔。

锦囊3 使用多个except子句分别捕获多种异常

在使用try…except语句时,也可添加多个except子句,用于捕获可能出现的多种异常,下面将应用两个except子句捕获执行除法运算时,可能出现的ZeroDivisionError和ValueError异常,代码如下:

def division():
    num1 = int(input('请输入被除数:')) 			# 用户输入提示,并记录
    num2 = int(input('请输入除数:'))
    result = num1//num2         				# 执行除法运算
    print(result)

if __name__ == '__main__':
    try:                         				# 捕获异常
        division()              				# 调用函数
    except ZeroDivisionError:  					# 处理异常
        print('\n出错了:除数不能为0!')
    except ValueError as e:    					# 处理ValueError异常
        print('输入错误:', e)  					# 输出错误原因

说明:如果还需要捕获更多种异常,可以继续添加except子句。

锦囊4 一次捕获全部异常

在使用try…except语句时,可以使用下面的代码一次捕获全部异常,代码如下:

def division():
    num1 = int(input('请输入被除数:')) 			# 用户输入提示,并记录
    num2 = int(input('请输入除数:'))
    result = num1//num2 						# 执行除法运算
    print(result)

if __name__ == '__main__':
    try:  										# 捕获异常
        division()  							# 调用函数
    except Exception as e:  					# 处理异常
        print('出错了:',e)

4. 【捕获异常】try…except…else语句

语法参考

try…except…else语句也是异常处理结构,它是在try…except语句的基础上再添加一个else子句,用于指定当try语句块中没有发现异常时要执行的语句块。当try语句中发现异常时,该语句块中的内容将不被执行。语法格式如下:

try:
    block1
except [ExceptionName [as alias]]:
    block2
else:
    block3

参数说明:

  • block1:表示可能出现错误的代码块。

  • ExceptionName [as alias]:可选参数,用于指定要捕获的异常。其中,ExceptionName表示要捕获的异常名称,如果在其右侧加上as alias则表示为当前的异常指定一个别名,通过该别名,可以记录异常的具体内容。

  • block2:表示进行异常处理的代码块。在这里可以输出固定的提示信息,也可以通过别名输出异常的具体内容。

  • block3:没有产生异常时执行的语句块。

锦囊1 捕获异常并在没有异常时给出提示

在执行除法运算时,捕获异常,并且实现当程序没有抛出异常时,输出运算结果,代码如下:

def division():
    num1 = int(input('请输入被除数:')) 		# 用户输入提示,并记录
    num2 = int(input('请输入除数:'))
    result = num1//num2                 	# 执行除法运算
    return result

if __name__ == '__main__':
    try:                                  	# 捕获异常
        result = division()             	# 调用函数
    except ZeroDivisionError:           	# 处理异常
        print('\n出错了:除数不能为0!')
    except ValueError as e:            		# 处理ValueError异常
        print('输入错误:', e)          		# 输出错误原因
    else:                                	# 没有抛出异常时执行
        print('结果为:',result)

5. 【捕获异常】try…except…finally语句

语法参考

完整的异常处理语句应该包含finally代码块,通常情况下,无论程序中有无异常产生,finally代码块中的代码都会被执行。其基本格式如下:

try:
    block1
except [ExceptionName [as alias]]:
    block2
finally:
    block3

对于try…except…finally语句的理解并不复杂,它只是比try…except语句多了一个finally语句,如果程序中有一些在任何情形中都必须执行的代码,那么就可以将它们放在finally语句的区块中。

说明:使用except子句是为了允许处理异常。无论是否引发了异常,使用finally子句都可以执行清理代码。如果分配了有限的资源(如打开文件),则应将释放这些资源的代码放置在finally块中。

锦囊1 在捕获异常时应用finally子句输出指定的提示信息

在执行除法运算时,实现当division()函数在执行时无论是否抛出异常,都输出文字“执行了除法运算”,代码如下:

def division():
    num1 = int(input('请输入被除数:')) 		# 用户输入提示,并记录
    num2 = int(input('请输入除数:'))
    result = num1//num2                 	# 执行除法运算
    return result

if __name__ == '__main__':
    try:                                  	# 捕获异常
        result = division()             	# 调用函数
    except ZeroDivisionError:           	# 处理异常
        print('\n出错了:除数不能为0!')
    except ValueError as e:            		# 处理ValueError异常
        print('输入错误:', e)          		# 输出错误原因
    else:                                	# 没有抛出异常时执行
        print('结果为:',result)
    finally:                            	# 无论是否抛出异常都执行
        print('\n执行了除法运算!')

锦囊2 在连接数据库时应用try…except…finally子句

在连接数据时,需要应用try…except语句捕获异常,并且无论是否抛出异常,都需要关闭数据库连接,这时就需要应用try…except…finally语句实现。在下面的代码,需要在else子句中,再嵌套一个try…except…finally处理创建数据表时可能出现的异常,代码如下:

import sqlite3  # 导入sqlite3模块

try:
    # 连接到SQLite数据库
    # 数据库文件是mrsoft.db,如果文件不存在,会自动在当前目录创建
    conn = sqlite3.connect('mrsoft.db')
except Exception as e:            		# 处理异常
    print(e)
else:
    try:
        cursor = conn.cursor()    		# 创建一个Cursor
        # 执行一条SQL语句,创建user表                   
        cursor.execute('create table user(id int(10) primary key,name varchar(20))')
    except Exception as e1:       		# 处理异常
        print(e1)
    finally:                      		# 无论是否抛出异常都执行
        cursor.close()            		# 关闭游标
finally:                          		# 无论是否抛出异常都执行
    conn.close()                  		# 关闭Connection
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值