Python基础--异常

1. 概念区分

  • 错误:
是由于逻辑或语法导致一个程序无法正常运行的问题, 错误的特点是有些错误是无法预知的
  • 异常:

通知上层调用者,有错误产生需要处理, 用作信号通知

是程序出错时标示的一种状态, 当异常发生时,程序不会向下继续执行,而转去调用此函数的地方,待处理此错误
  • python3 中常用的错误类型:
ZeroDivisionError 除(或取模)零
StopIteration 迭代器没有更多的值
IOError 输入输出操作失败
ImportError 导入模块失败
GeneratorExit 生成器发生异常通知退出
IndexError 序列中没有此索引
IndentationError 缩紧错误
ValueError 传入无效的参数
AssertionError 断言语句失败
NameError 未声明/初始化对象
AttributeError 对象没有

详见:>>> help(__builtins__)

2. 异常捕获

捕获异常,将程序转为正常流程

  • try-except语句语法:
try:
    可能触发异常的语句
except 错误类型1 [as 变量1]:
    异常处理语句1, 根据错误类型进行匹配,如果匹配成功,则程序转入正常状态,并调用处理语句进行处理
except 错误类型2 [as 变量2]:
    异常处理语句2
...
except:
    如果没有相应的错误类型与之匹配,则执行空类型的except子句(except:),之后程序进入正常状态; 如果没有该子句并且没有匹配到任何错误类型,则程序的异常状态会继续向上(调用处)传递,至入传入解释执行器后终止程序执行
    
else:
    未发生异常执行语句
finally:
    最终执行语句(一定会被执行)

说明:as 部分可以省略
     except 子句可以有一个或多个,但至少要有一个
     else 子句最多只能有一个,也可以省略不写
     finally 子句最多只能有一个,也可以省略不写
  • try-finally 语句语法:

try-finally语句不会改变程序的状态(正常/异常)状态, 用来做触发异常时必须处理的事情,无论异常是否发生,finally子句都会被执行; 通常try/finally 语句的finally 子句不可以省略,一定不存在except 子句;

try:
    可能触发异常的语句
finally:
    最终语句
def fry_egg():
    print("打开天然气!")
    print("开始煎鸡蛋!")
    try:
        n = int(input("请输入蛋的个数")) # 可触发异常
        print("完成煎蛋!共煎了%d个鸡蛋" % n)
    finally:
        print("关闭天然气!")

fry_egg()

打开天然气!
开始煎鸡蛋!
请输入蛋的个数a
关闭天然气!



---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-5-426dac8668b5> in <module>
      8         print("关闭天然气!")
      9 
---> 10 fry_egg()


<ipython-input-5-426dac8668b5> in fry_egg()
      3     print("开始煎鸡蛋!")
      4     try:
----> 5         n = int(input("请输入蛋的个数")) # 可触发异常
      6         print("完成煎蛋!共煎了%d个鸡蛋" % n)
      7     finally:


ValueError: invalid literal for int() with base 10: 'a'

3. raise 语句

触发一个错误,让程序进入异常状态

  • 语法
raise 异常类型 或 异常对象 
def make_raise():
    print("start")
    raise ZeroDivisionError("假的零除")
    print("end")

try:
    make_raise()
except ZeroDivisionError as err: # err绑定错误对象
    print("出现错误")
    print("错误类型:", err)
start
出现错误
错误类型: 假的零除

4. assert 语句(断言语句)

当真值表达式为False时, 用错误数据创建一个AssertionError类型的错误,并进入异常状态

  • 语法
assert 真值表达式, 错误数据(通常是字符串)

等同于:
if 真值表达式 == False:
    raise AssertionError(错误数据)
def get_age():
    a = input("请输入年龄:")
    a = int(a) # ValueError错误
    assert a < 150, "年龄太大了"
    assert a > 0, "还没出生"
    return a

while True: # 循环读入解决NameValue错误
    try:
        age = get_age() or 0
        break
    except AssertionError as e:
        print("发生年龄值不合法的错误,", e)
    except ValueError as e:
        print("发生输入值不能转为整数的错误", e)

print("您输入的年龄是:", age)
请输入年龄:a
发生输入值不能转为整数的错误 invalid literal for int() with base 10: 'a'
请输入年龄:1111
发生年龄值不合法的错误, 年龄太大了
请输入年龄:2
您输入的年龄是: 2

练习: 练习:写一个函数getscore() 获取学生输入的成绩(0~100),如果输入出现异常,则用 try-except语句来处理异常并此函数返回0,如果一切正常则返回输入的成绩

def get_score():
    score = int(input("输入学生成绩:"))
    if score < 0:
        raise ValueError("成绩小于零")
    if score > 100:
        raise ValueError("成绩大于零")
    return score

while True:
    try:
        score = get_score()
        break
    except ValueError as err:
        print("有错误发生:", err)

print("学生的成绩是:", score)
输入学生成绩:-1
有错误发生: 成绩小于零
输入学生成绩:111
有错误发生: 成绩大于零
输入学生成绩:a
有错误发生: invalid literal for int() with base 10: 'a'
输入学生成绩:12
学生的成绩是: 12

4. python 调试器 pdb模块

pdb是python debugger 调试器. 既可以在命令行执行python时进行调试,也可以作为模块被调用.

  • 运行python使用:
python -m pdb mysqcript.py 则会进入调试模式

(Pdb) # 会自动停在第一行,等待调试
  • 调试命令
1. 功能
h (help) # 帮助, 列出可用命令, h command 可用查看具体命令
q (quit) # 退出
!statement # 在目前的环境中执行statement (就是执行指定python语句)。
alias name command # 以一个”别名”代替”一群出错命令”,有点类似c/c++ 的 macro。可在.pdbrc文件内定义..
unalias name # 取消某个 alias定义的别名。
run # 重新运行脚本. 后面可以跟参数, 会覆盖原来sys.argv保存的参数. 2.6后新加.

2. 断点设置
b lineno (break) # 断点设置在本py的第 lineno 行, 或 b ots.py:20 #断点设置到 ots.py第20行. b funcname #断点设置到指定函数处; b # 查看所有断点编号及信息

tbreak lineno # 临时断点, 用法同break, 但只能断一次.
cl num (clear) # 删除第 num 个断点, num由b列出的Num列决定.如果没有带参数,则清除所有断点。也可指定行号.
condition bpnumber [condition] # 设置断点条件, 不写条件则会取消条件设置.
disable bpnumber # 取消指定断点的功能,但仍然保留断点可以重新激活。不指定 bpnumber会失效暂停所有断点.
enable bpnumber # 恢复断点的功能。

ignore bpnumber count # 设定断点的忽略次数。如果没指定count,其初始为0。当count为0时,断点会正常动作。若有指定 count,则每次执行到该中断,count就少1,直到count数为0。

commands bpnumber # 设置断点号处执行指定命令.使用该命令后进入cmd模式,然后可以输入相关要执行的命令, 输入end结束. 直接输入end会取消相应号的命令. 2.5版新加

3. 运行
c (continue) # 继续运行直到下个断点
n (next) # 单步运行, 不会进入函数内部而是直接到下一行.
s (step) # 单步运行, 但会进入到调用函数的内部.
r (return) # 继续执行直到函数返回处(return的地方).
j lineNo (jump) # 跳到某行执行,可以前跳或后跳。不是所有行都可跳. 只有在 call stack 的最底部才能作用。
unt (until) # 继续执行直到行号大于当前行. ?? 2.6后新加.

4. 查看
l (list) # 列出目前所在档案中的位置。->所指是现在所在代码(一般是可执行代码,默认上下5行). 连续地 l 命令会一直列到档案结尾。指定一个数字参数 n, 就是列出该行上下文; 两个参数n,m, 就是一个范围(n<m) 或指定行及以后的m行.

p var (print) # 查看变量 var 当前值
pp 和 p 命令类似,但是使用 pprint module。
a (args) # 查看全部栈内当前函数的参数变量
w (where) 列出目前call stack 中的所在层。(调用栈中的处理)
d (down) 在call stack中往下移一层 (较新).
u (up) 在call stack中往上移一层(较旧)。如果在上移一层之后按下 n ,则会在上移之后的一层执行下一个叙述,之前的 function call 就自动返回。
  • 在python中使用pdb模块可以进行调试.
import pdb

pdb.set_trace() : 设置断点, 在运行脚本到此时进入pdb模式, 指令则指到下一行.
pdb.run(statement, globals=None, locals=None): 主要用于调试指定内容语句块.
    statement: 要调试的语句块,以字符串的形式表示
    globals: 可选参数,设置statement运行的全局环境变量
    locals: 可选参数,设置statement运行的局部环境变量

pdb.runeval(statement, globals=None, locals=None): 和run类似, 但会对statement字符串先进行运算
pdb.runcall(funcname, *args, **kwds): 调试指定函数.后面可以指定传递的函数参数. 多参数要用,隔开.
pdb.post_mortem([traceback]): post-mortem调试模式处理traceback或新近的错.
pdb.pm(): post-mortem调试模式处理sys.last_traceback 的反馈

同名公众号: 庄AC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。 首先,让我们来谈谈 Python 中的异常处理。在 Python 中,异常是程序在运行时遇到的错误或问题,它会导致程序停止运行并抛出一个异常。为了避免这种情况,我们可以使用 try/except 块来捕获并处理异常。例如: ``` try: # some code that might raise an exception except SomeException: # handle the exception ``` 其中,SomeException 是你想要捕获的异常类型。当代码运行到 try 块中的代码时,如果出现了 SomeException 异常,那么 except 块中的代码就会被执行。 接下来,让我们来谈谈 Python 中的对象。在 Python 中,一切都是对象,包括数字、字符串、函数等等。对象有一个类型,它定义了对象可以执行的操作。例如,数字类型可以执行加、减、乘等操作,字符串类型可以执行拼接、切片等操作。你也可以创建自己的对象,并定义它们的类型和操作。 最后,让我们来谈谈 Python 中的迭代器。迭代器是一种对象,它可以让你逐个访问一个序列中的元素。Python 中的迭代器是通过 __iter__ 和 __next__ 方法实现的。__iter__ 方法返回一个迭代器对象,__next__ 方法返回序列中的下一个元素。例如: ``` class MyIterator: def __init__(self, data): self.data = data self.index = 0 def __iter__(self): return self def __next__(self): if self.index >= len(self.data): raise StopIteration result = self.data[self.index] self.index += 1 return result my_iter = MyIterator([1, 2, 3]) for item in my_iter: print(item) ``` 在上面的例子中,我们创建了一个名为 MyIterator 的迭代器对象。它有一个 data 属性,表示要迭代的序列,以及一个 index 属性,表示当前迭代的位置。__iter__ 方法返回 self,表示它本身就是一个迭代器对象。__next__ 方法返回序列中的下一个元素,并将 index 属性加 1。当迭代器遍历到序列末尾时,会抛出 StopIteration 异常,表示迭代结束。 希望这些信息能够对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值