1、什么是异常、什么是异常处理
异常是指程序在运行过程中发生的错误事件,影响程序的正常执行。异常并不是一定会发生,默认情况下,程序运行中遇到异常时将会终止,并在控制台打印出异常出现的堆栈信息。
异常处理是指程序设计时为了避免因异常而导致程序终止而做的一些额外操作。异常处理可以使得异常出现后,程序仍然可以执行。
(2)、常见的异常错误
In?[1]:
print(a) #变量未定义的异常
--------------------------------------------------------------------------- NameError Traceback (most recent call last) ~\AppData\Local\Temp\ipykernel_10324\4250713135.py in <module> ----> 1 print(a) #变量未定义的异常 NameError: name 'a' is not defined
In?[2]:
print('OK' #语法错误异常
File "C:\Users\Administrator\AppData\Local\Temp\ipykernel_10324\3139688914.py", line 1 print('OK' #语法错误异常 ^ SyntaxError: unexpected EOF while parsing
In?[3]:
list = [1,4,6,4] list[10] #下标索引异常
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) ~\AppData\Local\Temp\ipykernel_10324\277762902.py in <module> 1 list = [1,4,6,4] ----> 2 list[10] #下标索引异常 IndexError: list index out of range
In?[4]:
10/0 #除数为0,执行除法异常
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) ~\AppData\Local\Temp\ipykernel_10324\2083481908.py in <module> ----> 1 10/0 #除数为0,执行除法异常 ZeroDivisionError: division by zero
In?[6]:
a = input('a:') 10/a #执行了类型不支持的操作 改为int(input('a:'))
a:12
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) ~\AppData\Local\Temp\ipykernel_10324\428881340.py in <module> 1 a = input('a:') ----> 2 10/a #执行了类型不支持的操作 改为int(input('a:')) TypeError: unsupported operand type(s) for /: 'int' and 'str'
2、如何处理异常
Python中通常将可能发生异常的代码放在try语句中,
如果发生异常则通过except语句来捕获异常并对做一些额外处理,
如果没有发生异常则执行后面的else语句,
最后执行finally语句做一些收尾操作。
Python中还提供了raise语句允许用户主动抛出异常,raise关键字后面需要提供一个异常实例或者异常类,如果传递的是异常类,则会调用无参数的构造方法来实例化对象。如果捕获到了异常,但是暂时不处理,可以直接通过raise语句抛出异常,此时raise关键字后面什么都不用写。
In?[11]:
try: a = eval(input('请输入a:')) b = 10/a except: if a==0: print('ZeroDivisionError,除数不能为0!') else: print('b = ',b) print('表达式合法!') finally: c = a+b print('c = ',c)
请输入a:0 ZeroDivisionError,除数不能为0! c = 1.0
In?[12]:
B=[1,2, 3, 4,5] try: a=b[10] #(B和b应该一致) except IndexError: print('IndexError') except: print('Error') else: print('OK') finally: print('Exit')
Error Exit
In?[13]:
def test(a,b): #3、try... except...finally结构 try: c=a+b return c except Exception as e: print(e) #打印异常信息 c=[] return c finally: c.append(5) print("finally子句") print("finally语句中的c=",c) print("函数执行结束!") test([2],[4]) #调用函数,传递参数
finally子句 finally语句中的c= [2, 4, 5]
Out[13]:
[2, 4, 5]
In?[20]:
#实例:定义一个函数,验证密码字符串长度是不断为6-10, 不符合要求时抛出异常。(设置密码验证) def check_str(content): #用raise抛出自定义异常 if (len(content)<6 or len(content)>12): raise ValueError('长度应在6-12位之间,当前长度为:'+str(len(content))) #raise语句允许用户主动抛出异常 else: print('长度符合要求!') #调用函数,不捕获异常(发生异常时,打印异常堆栈信息) ss = input('请输入一个长度在6到12位之间的密码字符串:') check_str(ss)
请输入一个长度在6到12位之间的密码字符串:436457 长度符合要求!
可变长度参数是指函数定义时,无法确定参数的个数。例如系统中的 print函数,不知道用户需要打印多少个对象,此时将需要打印的内容定义为可变长度参数,根据调用者传递的实际参数来确定参数的长度。Python中可变长度参数有两种形式:*参数名和**参数名。
(1)*参数名:表示该参数是一个元组类型,可接受多个实参,并将传递的实参依次存放到元组中,主要针对以位置传值的实参;
(2)**参数名:表示该参数是一个字典类型,可接受多个实参,并将传递的键值对放到集合中,主要针对以关键字传值的实参。
In?[27]:
def fun_1(a,*b): print('a = ',a) print('b = ',b) fun_1(10,10,20,8,20,60) #b的值为元组
a = 10 b = (10, 20, 8, 20, 60)
In?[28]:
def fun_2(a,**b): print('a = ',a) print('b = ',b) fun_2(10,c=10,d=20,e=8,f=20,g=60) #b的值为字典
a = 10 b = {'c': 10, 'd': 20, 'e': 8, 'f': 20, 'g': 60}
根据变量定义的位置,可将变量分为全局变量和局部变量。
(1)全局变量:定义在函数外面的变量,可以在多个函数中进行访问,但不能执行赋值操作。如果有赋值语句,相当于创建了一个同名的局部变量;
(2)局部变量:定义在函数内部的变量,只能在它被定义的函数中使用。在函数外面无法直接访问。
(3)注意:当局部变量和全局变量同名时,在函数内部使用变量时,通常都是指局部变量,如果确实需要对全局变量进行修改,需要使用global关键字对变量进行声明,此时操作的就是全局变量了。
In?[30]:
def fun_3(): print(a) #在函数内部访问全局变量 a = 10 fun_3() print(a)
10 10
In?[31]:
def fun_4(): a = 8 #在函数内部定义同名的局部变量 print(a) a = 10 fun_4() print(a)
8 10
In?[34]:
def fun_5(): global a #在函数内部对全局变量操作(将局部变量转换成全局变量) a = 8 #给全局变量赋值 print('局部变量a = ',a) a = 10 #相当于局部变量的实参 fun_5() print('全局变量a = ',a)
局部变量a = 8 全局变量a = 8
In?[33]:
def fun_6(): a.append(12) #在全局变量为可变序列时,可直接在函数内部对全局变量操作 print(a) a = [1,2,3] fun_6() print(a)
[1, 2, 3, 12] [1, 2, 3, 12]
匿名函数1ambda表达式:没有函数名字的临时使用的函数,可以将1ambda表达式看成是函数的简写形式。
(1)lambda表达式的语法:
lambda 参数列表:表达式
(2)与函数区别:关键字不同:def、lambda;没有名称;参数列表不需要一对圆括号,只包含一个表达式,不能包含多条语句。
(3)lambda表达式的主体是一个表达式,而不是一个代码块,在表达式中可以调用其它函数,并支持默认值参数和关键字参数,表达式的结果相当于函数的返回值。
In?[39]:
#lambda表达式形式 lambda_func = lambda x:x * 2 #将lambda定义的函数赋值给一个变量 print(lambda_func(5)) print(lambda_func("5")) #函数形式 def lambda_func(x): return x * 2 print(lambda_func(5)) print(lambda_func("5"))
10 55 10 55
In?[36]:
x = 2 y = 3 z = 7 x+y+z
Out[36]:
12
In?[37]:
def test(x,y,z): return x+y+z test(2,3,7)
Out[37]:
12
In?[40]:
test = lambda x,y,z:x+y+z
In?[41]:
test(2,3,7)
Out[41]:
12
In?[49]:
teat2 = lambda x=4,y=6,z=12:x**2+y*2+z/3 teat2(4,6,12)
Out[49]:
32.0
1、元组:是不可变序列,不可修改里面的元素。元组中元素放在一对圆括号“()”中,并用逗号分隔,元素类型可以不同。注意:当元组中只包含一个元素时,元素后面的逗号不能省略,否则系统会将其看做是其他数据类型。
2、列表:是有序可变序列,列表的所有元素放在一对中括号“[]”中,并使用逗号隔开,元素的类型可以不同。
3、字符串:由字符组成的一个不可变序列,和元组作用类似,也支持索引、切片、重复、合并等操作。
4、字典:无序的映射类型,由若干”键(key):值(value)”组成,“键”和“值”之间用冒号隔开,所有“键值对”放在一对大括号“{}”内,并用逗号分隔。其中“键”必须为不可变类型,在同一个字典中,“键”必须是唯一的,但“值”可以重复。
5、集合:是无序可变不重复的,不支持索引、切片等操作。元素放在一对大括号“{}”中,并用逗号分隔,元素类型可以不同,但集合中元素不能重复。集合中不能包含可变元素,例如列表。注意:不能直接通过a={} 创建空集合,此时创建的是一个空字典。可通过循环遍历集合中的所有元素。