File "D:/python/study/day16/01 异常处理.py", line 1 print "hello word" ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print("hello word")? 以上运行输出结果中,前两段指明了错误的位置,最后一句表示出错的类型。在 Python 中,把这种运行时产生错误的情况叫做异常(Exceptions)。
异常类型 | 含义 |
---|---|
AssertionError | 当 assert 关键字后的条件为假时,程序运行会停止并抛出 AssertionError 异常 |
AttributeError | 当试图访问的对象属性不存在时抛出的异常 |
IndexError | 索引超出序列范围会引发此异常 |
KeyError | 字典中查找一个不存在的关键字时引发此异常 |
NameError | 尝试访问一个未声明的变量时,引发此异常 |
TypeError | 不同类型数据之间的无效操作 |
ZeroDivisionError | 除法运算中除数为 0 引发此异常 |
开发人员在编写程序时,难免会遇到错误,有的是编写人员疏忽造成的语法错误,有的是程序内部隐含逻辑问题造成的数据错误,还有的是程序运行时与系统的规则冲突造成的系统错误,等等。总的来说,编写程序时遇到的错误可大致分为 2 类,分别为语法错误和运行时错误。
python语法错误,不允许出现的错误,一旦出现需要立即进行修改
语法错误,也就是解析代码时出现的错误。当代码不符合python的语法规范时,python解释器就会在解析时进行报出SyntaxError语法错误,例如:
print "hello word" File "D:/python/study/day16/01 异常处理.py", line 1 print "hello word" ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print("hello word")?
python运行时错误,允许出现的错误,发生错误之后在进行修改,也是程序员基本工作之一,即改bug
运行时错误,即程序在语法上都是正确的,但是在运行的过程中发生了错误,例如:
a = 1/0 # 用1除以0,然后赋值给a 但是0作为除数是没有意义的,所以运行之后产生了如下错误: Traceback (most recent call last): File "D:/python/study/day16/01 异常处理.py", line 3, in <module> a = 1/0 ZeroDivisionError: division by zero
基本语法结构(针对性很强) try: 可能会出错的代码(被try监控) except 错误类型1 as e: # e就是具体错误的原因 对应错误类型1的解决措施 except 错误类型2 as e: # e就是具体错误的原因 对应错误类型2的解决措施 except 错误类型3 as e: # e就是具体错误的原因 对应错误类型3的解决措施 except 错误类型4 as e: # e就是具体错误的原因 对应错误类型4的解决措施 万能语法结构(笼统处理方式) # try: # word # except Exception as e: # print(e) # name 'word' is not defined 'password' # # try: # dic = {'name': 'jason'} # dic['password'] # except Exception as e: # print(e) # 'password' # # try: # 'jason' + 666 # except Exception as e: # print(e) # can only concatenate str (not "int") to str 其他异常捕获操作 try: name = 'tony' except Exception as e: print('异常错误,你是不是瞎了') else: print('try监测的代码没有出错的情况下正常运行结束 则会执行else子代码') finally: print('try监测的代码无论有没有出错,都会执行finally子代码') 断言 l1 = [11, 22, 33, 44, 55, 66] assert isinstance(l1, list) print('针对l1数据使用列表相关的操作') 主动抛异常 username = input('username>>>:') if username == '张三': raise NameError('法外狂徒张三已上线') # NameError: 法外狂徒张三已上线 else: print('who are you?')
1.for循环内部的本质 # 需求:使用while+异常捕获实现for循环的功能 l1 = [11, 22, 33, 44, 55, 66, 77, 88] res = l1.__iter__() while True: try: print(res.__next__()) except Exception as e: break
# def index(): # print('这是一个函数') # yield 111, 222, 333 # print('这是一个内置函数') # yield 222 # print('函数名加括号调用') # yield 333 """ 当函数体代码中有yield关键字 那么函数名第一次加括号调用不会执行函数体代码 而是由普通的函数变成了迭代器对象(生成器) 返回值 """ # print(index) # <function index at 0x000001F499F7A5E0> # res = index() # print(res) # <generator object index at 0x0000021E18BACA50> # res.__next__() # res.__next__() # res.__next__() """ yield可以在函数体代码中出现多次 每次调用__next__方法都会从上往下执行直到遇到yield代码停留在此处 """ # print(res.__next__()) # print(res.__next__()) # print(res.__next__()) # print(res.__next__()) """ yield后面如果有数据值 则会像return一样返回出去 如果有多个数据值逗号隔开 那么也会自动组织成元组返回 """
def index(name,food=None): print(f'{name}准备干午饭!!!') while True: food = yield print(f'{name}正在吃{food}') res = index('lisa') res.__next__() res.send('麻辣烫') # 传值并自动调用__next__方法 res.send('炒米粉') # 传值并自动调用__next__方法 res.send('螺蛳粉') # 传值并自动调用__next__方法
生成器本质就是一个迭代器对象,同样是为了节省内存空间 # l1 = [i**2 for i in range(10) if i > 3] # print(l1) # l1 = (i**2 for i in range(10) if i > 3) # print(l1) # <generator object <genexpr> at 0x000001A793439C10>