【Python基础篇】【19.异常处理】(附案例,源码)

异常处理

Python用异常对象(exception object)表示异常情况,遇到错误后,会引发异常。如果异常对象并未被处理或捕捉,程序就会用所谓的回溯(Traceback,一种错误信息)终止执行

可以简单的理解异常处理机制,就是在程序运行出现错误时,让 Python 解释器执行事先准备好的除错程序,进而尝试恢复程序的执行。

借助异常处理机制,甚至在程序崩溃前也可以做一些必要的工作,例如将内存中的数据写入文件、关闭打开的文件、释放分配的内存等。

Python 异常处理机制会涉及 try、except、else、finally 这 4 个关键字,同时还提供了可主动使程序引发异常的 raise 语句,

"""
捕获异常组合
try:
    可能发生错误的代码
except:
    如果出现异常执行的代码
如果出现的异常捕获到了, 那么不会影响后续的代码执行
"""
f = open('你好1.txt', mode='r', encoding='utf-8')  # r模式 是不会自动创建不存在的文件
print(f)  # 报错 FileNotFoundError: [Errno 2] No such file or directory: '你好1.txt'

try:
    f = open('你好1.txt', mode='r', encoding='utf-8')
except:
    f = open('你好1.txt', mode='w', encoding='utf-8')

常见异常

# 先赋值声明后使用
print(name)  
"""
    NameError: name 'name' is not defined
    名称错误:name 没有被定义
"""

# 被除数是不能为0的
print(10 / 0)
"""
    ZeroDivisionError: division by zero
    除零错误:任何数值被零除都会导致ZeroDivisionError错误
"""

# 索引错误
a = [1, 3, 4, 5]
print(a[20])
"""
    IndexError: list index out of range
    索引错误:使用一个超出范围的值索引时引发
"""

dic1 = {
    'age': 18,
    'name': '泽言'
}
print(dic1['kk'])
"""
    KeyError: 'kk'
    键错误:该字典没有这个键引发的报错
"""


# 捕获错误
try:
    print(10 / 0)
    print(name)
except NameError: # 指定的捕获异常
    print('有错误')
    
    
# 捕获多个异常
try:
    print(10 / 0)
    print(name)
except (NameError, ZeroDivisionError):  # 指定的捕获异常
    print('有错误')
    
    
# 捕获所有异常
try:
    print(10 / 0)
    print(name)
except Exception:  # 捕捉所有异常(你打印的错误要是我当前Exception里面收录好了)  记录了 99%
    print('有错误')
    
    
# 显示打印异常的信息
try:
    print(10 / 0)
    print(name)  # 如果存在多个异常,他只会打印第一个异常信息,但是能捕捉所有的异常
except Exception as e:  # 只是一个变量,名字随便取
    print(e)

else

在原本的 try except 结构的基础上,Python 异常处理机制还提供了一个 else 块,也就是原有 try except 语句的基础上再添加一个 else 块,即try except else结构。

使用 else 包裹的代码,只有当 try 块没有捕获到任何异常时,才会得到执行;反之,如果 try 块捕获到异常,即便调用对应的 except 处理完异常,else 块中的代码也不会得到执行。

# else 当 try 代码块下面的代码没有异常的时候才会被执行
try:
    print(111)
except Exception as r:
    print(r)
else:
    print('我是else,当try代码块下面的代码没有异常的时候我会被执行')
    
''' 示例 '''
try:
    result = 20 / int(input('请输入除数:'))
    print(result)
except ValueError:
    print('必须输入整数')
except ArithmeticError:
    print('算术错误,除数不能为 0')
else:
    print('没有出现异常')
print("继续执行")

finally

Python 异常处理机制还提供了一个 finally 语句,通常用来为 try 块中的程序做扫尾清理工作。
注意,和 else 语句不同,finally 只要求和 try 搭配使用,而至于该结构中是否包含 except 以及 else,对于 finally 不是必须的(else 必须和 try except 搭配使用)。

在整个异常处理机制中,finally 语句的功能是:无论 try 块是否发生异常,最终都要进入 finally 语句,并执行其中的代码块。

基于 finally 语句的这种特性,在某些情况下,当 try 块中的程序打开了一些物理资源(文件、数据库连接等)时,由于这些资源必须手动回收,而回收工作通常就放在 finally 块中。
Python 垃圾回收机制,只能帮我们回收变量、类对象占用的内存,而无法自动完成类似关闭文件、数据库连接等这些的工作。

读者可能会问,回收这些物理资源,必须使用 finally 块吗?当然不是,但使用 finally 块是比较好的选择。首先,try 块不适合做资源回收工作,因为一旦 try 块中的某行代码发生异常,则其后续的代码将不会得到执行;其次 except 和 else 也不适合,它们都可能不会得到执行。而 finally 块中的代码,无论 try 块是否发生异常,该块中的代码都会被执行。

# finally 不管 try 代码块下的代码有没有异常,都会被执行
try:
    print(name)
except Exception as r:
    print(r)
else:
    print('我是else,当try代码块下面的代码没有异常的时候我会被执行')
finally:
    print('我是finally, 不管try代码块下面的代码有没有异常, 我都会被执行')

raise

是否可以在程序的指定位置手动抛出一个异常?
答案是肯定的,Python 允许我们在程序中手动设置异常,使用 raise 语句即可。

你可能会疑惑,从来都是想方设法地让程序正常运行,怎么还要手动设置异常呢?
首先要分清楚程序发生异常和程序执行错误,它们完全是两码事:程序由于错误导致的运行异常,是需要程序员想办法解决的;但还有一些异常,是程序正常运行的结果,比如用 raise 手动引发的异常。

当程序出现错误,python会自动引发异常,也可以通过raise显示地引发异常一旦执行了raise语句,raise后面的语句将不能执行。

raise [exceptionName [(reason)]]

用 [] 括起来的为可选参数,其作用是指定抛出的异常名称,以及异常信息的相关描述。如果可选参数全部省略,则 raise 会把当前错误原样抛出;如果仅省略 (reason),则在抛出异常时,将不附带任何的异常描述信息。

''' raise的三种情况 '''
# 1. 单独一个 raise 
# 单独的raise会重新触发前一个异常,如果之前没有触发异常,触发RuntimeError
# 第一种情况:上下文中捕获的异常
def test(num):
    try:
        100/num
    except Exception as res:
        print("捕获异常完成")
        raise  
test(0)

# 第二种情况:默认引发RuntimeError 异常:
def test(num):
    if num == 100:
        raise
    print(num)
test(100)

# 2. raise 异常名称
def Test1(num):
    try:
        100/num
    except Exception as res:
        print("捕获异常完成")
        print(res)
        raise ZeroDivisionError
        print("----在raise之后,不会执行-----")
    else:
        print("没有异常")
Test1(0)

# 其中 异常名称可以为自定义异常名称 
class CustomException(Exception):
    def __init__(self,ErrorInfo):
        self.ErrorInfo = ErrorInfo
    def __str__(self):
        return self.ErrorInfo
def Test1(num):
    try:
        raise CustomException('这是一个自定义的异常')
    except CustomException as res:
        print(res)
Test1(0)

# 3.raise 异常名称(异常描述信息)
def Test1(num):
    try:
        100/num
    except Exception as res:
        print("捕获异常完成")
        print(res)
        raise ZeroDivisionError("分母不能为0")
        print("----在raise之后,不会执行-----")
    else:
        print("没有异常")
Test1(0)


''' 示例 '''
def div(a, c):
    try:
        if c == 0:
            raise Exception('c不能等于0')  # 主动抛出的一个异常,不是系统报错
        return a / c
    except Exception as e:
        print(e)  # 打印报错信息

# print(div(5,0))
print(div(7, 6))

''' 示例 '''
try:
    a = input("输入一个数:")
    #判断用户输入的是否为数字
    if(not a.isdigit()):
        raise ValueError("输入的%s不是数字,要求必须输入数字"%(a))
except ValueError as e:
    print("引发异常:", repr(e))

print("输错了,异常发生,本程序也没有崩溃,正常运行到结束!!!")

获取异常信息

在实际调试程序的过程中,有时只获得异常的类型是远远不够的,还需要借助更详细的异常信息才能解决问题。

捕获异常时,有 2 种方式可获得更多的异常信息,分别是:

  • 使用 sys 模块中的 exc_info 方法;
  • 使用 traceback 模块中的相关函数

sys.exc_info()

使用 sys 模块中的 exc_info() 方法获得更多的异常信息。
后续我们会接受模块的详细信息,先简单了解一下。

模块 sys 中,有两个方法可以返回异常的全部信息,分别是 exc_info() 和 last_traceback(),这两个函数有相同的功能和用法,以 exc_info() 方法为例。

exc_info() 方法会将当前的异常信息以元组的形式返回,该元组中包含 3 个元素,分别为 type、value 和 traceback,它们的含义分别是:

  • **type:**异常类型的名称,它是 BaseException 的子类
  • **value:**捕获到的异常实例。
  • **traceback:**是一个 traceback 对象。
# 使用 sys 模块之前,需使用 import 引入
import sys

try:
    x = int(input("请输入一个被除数:"))
    print("30除以", x, "等于", 30 / x)
except:
    print(sys.exc_info())
    print("其他异常...")
# 当输入 0 时,程序运行结果为:
# 请输入一个被除数:0
# (<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero',), <traceback object at 0x000001FCF638DD48>)
# 其他异常...

'''
输出结果中,第 2 行是抛出异常的全部信息,这是一个元组,有 3 个元素,第一个元素是一个 ZeroDivisionError 类;第 2 个元素是异常类型 ZeroDivisionError 类的一个实例;第 3 个元素为一个 traceback 对象。其中,通过前 2 个元素可以看出抛出的异常类型以及描述信息,对于第 3 个元素,是一个 traceback 对象,无法直接看出有关异常的信息,还需要对其做进一步处理。

要查看 traceback 对象包含的内容,需要先引进 traceback 模块,然后调用 traceback 模块中的 print_tb 方法,并将 sys.exc_info() 输出的 traceback 对象作为参数参入。例如:
'''
# 使用 sys 模块之前,需使用 import 引入
import sys
# 引入traceback模块
import traceback

try:
    x = int(input("请输入一个被除数:"))
    print("30除以", x, "等于", 30 / x)
except:
    # print(sys.exc_info())
    traceback.print_tb(sys.exc_info()[2])
    print("其他异常...")
# 输入 0,程序运行结果为:
# 请输入一个被除数:0
#   File "C:\Users\mengma\Desktop\demo.py", line 7, in <module>
#     print("30除以",x,"等于",30/x)
# 其他异常...
# 可以看到,输出信息中包含了更多的异常信息,包括文件名、抛出异常的代码所在的行数、抛出异常的具体代码。

traceback

除了使用 sys.exc_info() 方法获取更多的异常信息之外,还可以使用 traceback 模块,该模块可以用来查看异常的传播轨迹,追踪异常触发的源头

class SelfException(Exception):
    pass

def main():
    firstMethod()

def firstMethod():
    secondMethod()

def secondMethod():
    thirdMethod()

def thirdMethod():
    raise SelfException("自定义异常信息")

main()
'''
上面程序中 main() 函数调用 firstMethod(),firstMethod() 调用 secondMethod(),secondMethod() 调用 thirdMethod(),thirdMethod() 直接引发一个 SelfException 异常。
Traceback (most recent call last):
  File "C:\Users\mengma\Desktop\1.py", line 11, in <module>
    main()
  File "C:\Users\mengma\Desktop\1.py", line 4, in main                   <--mian函数
    firstMethod()
  File "C:\Users\mengma\Desktop\1.py", line 6, in firstMethod        <--第三个
    secondMethod()
  File "C:\Users\mengma\Desktop\1.py", line 8, in secondMethod   <--第二个
    thirdMethod()
  File "C:\Users\mengma\Desktop\1.py", line 10, in thirdMethod     <--异常源头
    raise SelfException("自定义异常信息")
SelfException: 自定义异常信息

'''

从输出结果可以看出,异常从 thirdMethod() 函数开始触发,传到 secondMethod() 函数,再传到 firstMethod() 函数,最后传到 main() 函数,在 main() 函数止,这个过程就是整个异常的传播轨迹。

在实际应用程序的开发中,大多数复杂操作都会被分解成一系列函数或方法调用。这是因为,为了具有更好的可重用性,会将每个可重用的代码单元定义成函数或方法,将复杂任务逐渐分解为更易管理的小型子任务。由于一个大的业务功能需要由多个函数或方法来共同实现,在最终编程模型中,很多对象将通过一系列函数或方法调用来实现通信,执行任务。

所以,当应用程序运行时,经常会发生一系列函数或方法调用,从而形成“函数调用战”。异常的传播则相反,只要异常没有被完全捕获(包括异常没有被捕获,或者异常被处理后重新引发了新异常),异常就从发生异常的函数或方法逐渐向外传播,首先传给该函数或方法的调用者,该函数或方法的调用者再传给其调用者,直至最后传到 Python 解释器,此时 Python 解释器会中止该程序,并打印异常的传播轨迹信息。
很多初学者一看到输出结果所示的异常提示信息,就会惊慌失措,他们以为程序出现了很多严重的错误,其实只有一个错误,系统提示那么多行信息,只不过是显示异常依次触发的轨迹。

其实,上面程序的运算结果显示的异常传播轨迹信息非常清晰,它记录了应用程序中执行停止的各个点。最后一行信息详细显示了异常的类型和异常的详细消息。从这一行向上,逐个记录了异常发生源头、异常依次传播所经过的轨迹,并标明异常发生在哪个文件、哪一行、哪个函数处。

使用 traceback 模块查看异常传播轨迹,首先需要将 traceback 模块引入,该模块提供了如下两个常用方法:

  • **traceback.print_exc():**将异常传播轨迹信息输出到控制台或指定文件中。
  • **format_exc():**将异常传播轨迹信息转换成字符串。

可能有读者好奇,从上面方法看不出它们到底处理哪个异常的传播轨迹信息。实际上我们常用的 print_exc() 是 print_exc([limit[, file]]) 省略了 limit、file 两个参数的形式。而 print_exc([limit[, file]]) 的完整形式是 print_exception(etype, value, tb[,limit[, file]]),在完整形式中,前面三个参数用于分别指定异常的如下信息:

  • **etype:**指定异常类型;
  • **value:**指定异常值;
  • **tb:**指定异常的traceback 信息;

当程序处于 except 块中时,该 except 块所捕获的异常信息可通过 sys 对象来获取,其中 sys.exc_type、sys.exc_value、sys.exc_traceback 就代表当前 except 块内的异常类型、异常值和异常传播轨迹。

简单来说, print_exc([limit[, file]]) 相当于如下形式:
print_exception(sys.exc_etype, sys.exc_value, sys.exc_tb[, limit[, file]])

也就是说,使用 print_exc([limit[, file]]) 会自动处理当前 except 块所捕获的异常。该方法还涉及两个参数:
limit:用于限制显示异常传播的层数,比如函数 A 调用函数 B,函数 B 发生了异常,如果指定 limit=1,则只显示函数 A 里面发生的异常。如果不设置 limit 参数,则默认全部显示。
file:指定将异常传播轨迹信息输出到指定文件中。如果不指定该参数,则默认输出到控制台。

借助于 traceback 模块的帮助,我们可以使用 except 块捕获异常,并在其中打印异常传播信息,包括把它输出到文件中。例如如下程序:

# 导入trackback模块
import traceback
class SelfException(Exception): pass
def main():
    firstMethod()
def firstMethod():
    secondMethod()
def secondMethod():
    thirdMethod()
def thirdMethod():
    raise SelfException("自定义异常信息")
try:
    main()
except:
    # 捕捉异常,并将异常传播信息输出控制台
    traceback.print_exc()
    # 捕捉异常,并将异常传播信息输出指定文件中
    traceback.print_exc(file=open('log.txt', 'a'))

上面程序第一行先导入了 traceback 模块,接下来程序使用 except 捕获程序的异常,并使用 traceback 的 print_exc() 方法输出异常传播信息,分别将它输出到控制台和指定文件中。
运行上面程序,同样可以看到在控制台输出异常传播信息,而且在程序目录下生成了一个 log.txt 文件,该文件中同样记录了异常传播信息。

处理异常基本原则

使用异常处理的优势、便捷之处,本节将进一步从程序性能优化、结构优化的角度给出异常处理的一般规则。成功的异常处理应该实现如下4个目标。

  • 使程序代码混乱最小化
  • 捕获并保留诊断信息
  • 通知合适的人员
  • 采用合适的方式结束异常活动。

为了实现以上目标,我们应做到:

  1. 不过度使用异常
    区分异常与普通错误,能处理的错误要通过代码处理,而不是简单的抛出异常,不要使用异常捕获来代替流程控制,这样做程序的执行效率会很低。
  2. 避免过于庞大的try块
    过大的try块会导致容易出错,而且排查错误困难。
    如果必须将很多语句进行异常捕获,尽量拆分成小的try块,方便调试。
  3. 不要忽略捕获的异常
    既然已经发现了异常,就要及时处理,避免引起程序崩溃,仅仅打印异常信息,会稍微好一点,但还是建议对异常采取适当的措施。

例如:

  • 用别的数据进行计算,以替代期望方法的返回值
  • 提示用户重新操作
  • 把在当前运行环境下能做的事情尽量做完,然后进行异常转移,把异常包装成当前层的异常,重新传给上传调用者
  • 在合适的层处理异常,如果本层不清楚如何处理,就不要在当前层使用except语句来捕获,让上层调用着来负责处理该异常。

assert

使用 assert 断言语句是一个非常好的习惯,python assert 断言句语格式及用法很简单。在没完善一个程序之前,我们不知道程序在哪里会出错,与其让它在运行到最后崩溃,不如在出现错误条件时就崩溃,这样在跑大规模程序的时候不会过多的浪费时间和计算资源,这时候就需要assert断言的帮助。

  • Python assert(断言)用于判断一个表达式,要求表达式计算值必须为真。可用于自动调试。如果表达式为假,触发异常;如果表达式为真,不会报错。
def div(a, c):
    # assert 后面的布尔结果为False就会触发断言  后面的布尔结果为True就不会触发断言
    print(c != 0)  # True
    assert c != 0, 'c不能为0,kkk+3344'  # 这个是我们自己定义报错,不是系统自己的报错
    return a / c

# print(div(8,0))
print(div(5, 7))  # 0.7142857142857143

''' 示例 '''
def  zero(s):
    a = int(s)
    assert a > 0,"a超出范围"   #这句的意思:如果a确实大于0,程序正常往下运行
    return a

zero("-2")  #但是如果a是小于0的,程序会抛出AssertionError错误,报错为参数内容“a超出范围”

断点调试

Pycharm的用户,通常都喜欢Pycharm强大的debug配置。但pycharm虽好,但需要图形化的UI界面,事实上在很多项目开发上有UI界面是很奢侈的事情。所以在无界面的vim下debug,难道只能用print了?那效率就太低下了。

事实上,python有内置的断点工具,直接在代码中插入即可完成断点调试。

arr = [1, 2, 3, 4, 5]
index = 0

def print_item(item):
    print(item)


while index < len(arr):
    print_item(arr[index])
    index += 1

# 步过   会一步一步单步的调试代码 但是遇到函数是不会进入的
# 步入   可以进入到我们的内函数内部去执行操作
# 单步执行我的代码  他会一步一步的执行,遇到函数是会自动进入的
# 步出   是可以跳出函数内部的执行
# 运行到我的光标出   你的鼠标光标在哪里name他就会运行到哪里

for i in range(10):  # 起始值值不写默认从0开始 ,左闭右开的结果
    print(i)

两种方式

1、在代码区域,鼠标右键,选中Debug开始调试(推荐)

在这里插入图片描述

2、点击代码区域右上角的虫子图标

注意选择正确的文件,在虫子图标的左侧,如选错了,就是给其他文件Debug了

在这里插入图片描述

开始进入Debug调试模式后,程序会运行到第一个断点,可以在代码后面或者Debugger工具面板查看变量值

在这里插入图片描述

Debugger窗口各图标的含义

在这里插入图片描述

1.Show Execution Point (Alt + F10)
  • 作用是定位当前执行点,在调试过程中,代码可能会在多个断点之间跳转,或者通过函数调用进入不同的代码块,使用"Show Execution Point"功能,可以方便地看到当前正在执行的代码行,而无需手动滚动代码窗口。
2.Step Over(F8)
  • 调试过程中,如果想逐行执行代码并查看每一行的执行结果,但不希望进入函数调用的内部代码,而是直接执行完整个函数并跳过它 ,就可以使用它,在不存在子函数的情况下是和Step Into效果一样的(简而言之,越过子函数,但子函数会执行)

  • 举个例子,有以下Python代码,设置断点, 点击 Debugger 窗口的 “Step Over” 按钮(或按下 F8 键) ,可以看到没有进入multiply(a,y)函数,直接计算出product_result的值了。

3.Step Into (F7)
  • 单步执行,遇到子函数就进入并且继续单步执行(简而言之,进入子函数)。

  • 举个例子,有以下Python代码,设置断点, 点击 Debugger 窗口的 “Step Into” 按钮(或按下 F7 键) ,可以看到进入multiply(a,y)函数了。

4.Step Into My Code(Alt + Shift + F7)
  • 进入自己编写的函数,但不进入系统函数,很少用到。
5.Force Step Into(Alt + Shift + F7)
  • 强制进入,在调试的时候能进入任何方法, 它允许你在遇到多个可以进入的函数调用时,自行选择要进入的函数,而不是按照默认的逐层进入顺序。

  • 举个例子, 有以下Python代码,假设你在调试模式下启动了这段代码,并在 sum_result = add(num1, num2) 这一行设置了断点。当代码停在这个断点处时,你可以点击 Debugger 窗口的 “Step Into” 按钮(或按下 F7 键)来进入 add() 函数的内部。

  • 现在,如果你想进入 divide(product_result, num2) 这个函数调用的内部,你可以在 Debugger 窗口中右键点击 divide 这一行,然后选择 “Force Step Into”。这将会强制 Debugger 跳过 multiply() 函数内部的逐行执行,直接进入 divide() 函数内部。

6.Step Out( Shift + F8)
  • 当单步执行到子函数内时,用Step Out就可以执行完子函数余下部分,并返回到上一层函数。 “Step Over” 是逐行执行并忽略函数内部的操作,而 “Step Out” 是从当前函数内部退出并继续执行到调用点的操作。

  • 举个例子,有以下Python代码,在sum_result = add(num1, num2)处打断点,代码执行进入add函数后,点击Step Out,直接跳出add函数,但是还是会计算出sum_result的值。

7.Run to Cursor( Alt + F9)
  • 一直执行,到光标处停止,用在循环内部时,点击一次就执行一个循环。它是一个非常实用的功能,可以帮助你快速运行代码片段,跳过不必要的中间步骤,以及在你只关心特定部分的情况下更高效地进行调试。

  • 举个例子,有以下Python代码,假设你在调试模式下启动了这段代码,并在 num1 = 5 这一行设置了断点。现在,如果你想要跳过 add(num1, num2) 函数调用的逐步执行,直接执行到 print(“Sum:”, sum_result) 这一行,你可以在该行上右键点击,然后选择 “Run to Cursor”。

  • 这将会让程序在当前位置直接运行,直到光标所在的位置。在这个例子中,它将跳过 add() 函数的内部执行,直接执行到 print(“Sum:”, sum_result) 这一行,然后停止。

8.Evaluate Expression ( Alt + F8)
  • 计算表达式。 这个功能对于查看变量、计算表达式、验证假设以及调试代码时的实时观察非常有帮助,可以动态地在断点处计算和查看不同表达式的值,更好地理解代码在不同步骤的状态,以及发现潜在的问题。

  • 举个例子,有以下Python代码,假设你在调试模式下启动了这段代码,并在 sum_result = add(num1, num2) 这一行设置了断点。当代码停在这个断点处时,你可以使用 “Evaluate Expression” 功能来计算和查看一些表达式的值。

  • 例如,你可以在调试器的窗口中找到 “Evaluate Expression” 输入框,然后输入表达式 num1 + num2 并点击 “Evaluate” 按钮。这将会计算 num1 和 num2 的和,然后显示结果。

在这里插入图片描述

9.Return XXX(Ctrl + F5)
  • 重新运行程序,会关闭服务后重新启动程序。
10.Resume Program (F9)
  • 允许你从一个断点处恢复程序的执行,跳过你不想逐步检查的部分,以便你能够更快地观察代码的整体行为。

  • 比如,你在第20行和26行有两个断点,当前运行至第20行,按F9,则运行到下一个断点(即第26行),再按F9,则运行完整个流程,因为后面已经没有断点了。

11.Pause Program
  • 暂停程序,启用Debug, 以便能够检查当前的状态、变量的值,或者观察代码的执行情况,完成了查看和调试操作后,可以继续执行程序,通常是通过点击调试器工具栏上的 “Resume Program”(通常是一个绿色的三角形图标)来恢复程序的执行 。
12.Stop ‘xxx’ (Ctrl + F2)
  • 允许立即停止程序的执行和调试会话,适用于需要立即中止调试过程的情况。有时候会发现关闭服务再启动时,报端口被占用,这是因为没完全关闭服务的原因,这个时候就需要查杀所有JVM进程了。
13.View Breakpoints (Ctrl + Shift + F8)
  • 能够查看和管理代码中设置的断点,帮助更好地进行调试和观察程序的执行流程。

在这里插入图片描述

14.Mute Breakpoints
  • 一次性临时禁用所有断点,而不必逐个去禁用每个断点 ,在不删除断点的情况下,暂时停止断点的触发,以便在某些特定情况下进行调试或测试时非常有用。

  • 选择这个后,所有断点变为灰色,断点失效,按F9则可以直接运行完程序。再次点击,断点变为红色,有效。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

My.ICBM

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

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

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

打赏作者

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

抵扣说明:

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

余额充值