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

异常处理

  • 异常处理
    • 常见异常
    • else
    • finally
    • raise
    • 获取异常信息
      • sys.exc_info()
      • traceback
    • 处理异常基本原则
    • assert
    • 断点调试
      • 两种方式
      • Debugger窗口各图标的含义
          • 1.Show Execution Point (Alt + F10)
          • 2.Step Over(F8)
          • 3.Step Into (F7)
          • 4.Step Into My Code(Alt + Shift + F7)
          • 5.Force Step Into(Alt + Shift + F7)
          • 6.Step Out( Shift + F8)
          • 7.Run to Cursor( Alt + F9)
          • 8.Evaluate Expression ( Alt + F8)
          • 9.Return XXX(Ctrl + F5)
          • 10.Resume Program (F9)
          • 11.Pause Program
          • 12.Stop 'xxx' (Ctrl + F2)
          • 13.View Breakpoints (Ctrl + Shift + F8)
          • 14.Mute Breakpoints

异常处理

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/numexcept Exception as res:print("捕获异常完成")raise  
test(0)# 第二种情况:默认引发RuntimeError 异常:
def test(num):if num == 100:raiseprint(num)
test(100)# 2. raise 异常名称
def Test1(num):try:100/numexcept Exception as res:print("捕获异常完成")print(res)raise ZeroDivisionErrorprint("----在raise之后,不会执行-----")else:print("没有异常")
Test1(0)# 其中 异常名称可以为自定义异常名称 
class CustomException(Exception):def __init__(self,ErrorInfo):self.ErrorInfo = ErrorInfodef __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/numexcept 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 / cexcept 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 systry: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 tracebacktry: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):passdef 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)  # Trueassert 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 azero("-2")  #但是如果a是小于0的,程序会抛出AssertionError错误,报错为参数内容“a超出范围”

断点调试

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

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

arr = [1, 2, 3, 4, 5]
index = 0def 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则可以直接运行完程序。再次点击,断点变为红色,有效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2659532.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【线性代数】通过矩阵乘法得到的线性方程组和原来的线性方程组同解吗?

一、通过矩阵乘法得到的线性方程组和原来的线性方程组同解吗&#xff1f; 如果你进行的矩阵乘法涉及一个线性方程组 Ax b&#xff0c;并且你乘以一个可逆矩阵 M&#xff0c;且产生新的方程组 M(Ax) Mb&#xff0c;那么这两个系统是等价的&#xff1b;它们具有相同的解集。这…

k8s二进制部署2

部署 Worker Node 组件 //在所有 node 节点上操作 #创建kubernetes工作目录 mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs} #上传 node.zip 到 /opt 目录中&#xff0c;解压 node.zip 压缩包&#xff0c;获得kubelet.sh、proxy.sh cd /opt/ unzip node.zip chmod x kubelet.…

CodeWhisperer——轻松使用一个超级强大的工具

CodeWhisperer 简介 CodeWhisperer是亚⻢逊云科技出品的一款基于机器学习的通用代码生成器&#xff0c;可实时提供代码建议。 CodeWhisperer有以下几个主要用途&#xff1a; 解决编程问题&#xff0c;提供代码建议&#xff0c;学习编程知识等等&#xff0c;并且CodeWhisper…

2022 年全国职业院校技能大赛高职组云计算正式赛卷第二场-容器云

2022 年全国职业院校技能大赛高职组云计算赛项试卷 云计算赛项第二场-容器云 目录 2022 年全国职业院校技能大赛高职组云计算赛项试卷 【赛程名称】云计算赛项第二场-容器云 【任务 1】容器云平台搭建[5 分] 【任务 2】容器云应用部署&#xff1a; Docker Compose 编排部署[7.0…

【ZYNQ】教你用 Vivado HLS 快速设计一个 IP

Xilinx 推出的 Vivado HLS 工具可以直接使用 C、C或 System C 来对 Xilinx 系列的 FPGA 进行编程&#xff0c;从而提高抽象的层级&#xff0c;大大减少了使用传统 RTL 描述进行 FPGA 开发所需的时间。 Vivado HLS 的功能简单地来说就是把 C、C 或 SystemC 的设计转换成 RTL 实…

Python自动化测试:选择最佳的自动化测试框架

在开始学习python自动化测试之前&#xff0c;先了解目前市场上的自动化测试框架有哪些&#xff1f; 随着技术的不断迭代更新&#xff0c;优胜劣汰也同样发展下来。从一开始工具型自动化&#xff0c;到现在的框架型&#xff1b;从一开始的能用&#xff0c;到现在的不仅能用&…

element el-table实现可进行横向拖拽滚动

【问题】表格横向太长&#xff0c;表格横向滚动条位于最底部&#xff0c;需将页面滚动至最底部才可左右拖动表格&#xff0c;用户体验感不好 【需求】基于elment的el-table组件生成的表格&#xff0c;使其可以横向拖拽滚动 【实现】灵感来源于这篇文章【Vue】表格可拖拽滚动&am…

每周一算法:区间覆盖

问题描述 给定 N N N个闭区间 [ a i , b i ] [a_i,b_i] [ai​,bi​]&#xff0c;以及一个线段区间 [ s , t ] [s,t] [s,t]&#xff0c;请你选择尽量少的区间&#xff0c;将指定线段区间完全覆盖。 输出最少区间数&#xff0c;如果无法完全覆盖则输出 − 1 -1 −1。 输入格式…

androj环境搭建_AS安装及运行源码

1、 jdk安装 安卓项目也是java开发的&#xff0c;运行在虚拟机上&#xff0c;安装jdk及运行的时候&#xff0c;就会自动生成虚拟机&#xff0c; jdk前面已经讲过&#xff0c;这里不在讲解 2、下载安装androj studio https://developer.android.google.cn/studio?hlzh-cn 下…

mysql原理---InnoDB统计数据是如何收集的

以下聚焦于 InnoDB 存储引擎的统计数据收集策略。 1.两种不同的统计数据存储方式 InnoDB 提供了两种存储统计数据的方式&#xff1a; (1). 永久性的统计数据 这种统计数据存储在磁盘上&#xff0c;也就是服务器重启之后这些统计数据还在。 (2). 非永久性的统计数据 这种统计数…

Java生态系统的进化:从JDK 1.0到今天

目录 前言 JDK 1.0&#xff1a;开启Java时代 JDK 1.1&#xff1a;Swing和内部类 JDK 1.2&#xff1a;Collections框架和JIT编译器 JDK 1.5&#xff1a;引入泛型和枚举 JDK 1.8&#xff1a;Lambda表达式和流 JDK 11以后&#xff1a;模块化和新特性 未来展望 总结 作者简…

Smartbi获工信部旗下赛迪网“2023行业信息技术应用创新产品”奖

近日&#xff0c;由工信部旗下的赛迪网、《数字经济》杂志共同主办的2023行业信息技术应用创新大会上&#xff0c;“信息技术应用创新成果名单”重磅揭晓&#xff0c;思迈特软件凭借“Smartbi 自然语言分析引擎”斩获“2023行业信息技术应用创新产品”大奖。 据了解&#xff0c…

JavaWeb——监听器Listener 过滤器Filter——韩顺平学习笔记

文章目录 JavaWeb 三大组件之监听器 ListenerListenerJavaWeb 的监听器ServletContextListener 监听器ServletContextAttributeListener 监听器其它监听器-使用较少HttpSessionListener 监听器HttpSessionAttributeListener 监听器ServletRequestListener 监听器ServletRequest…

YOLOv5算法进阶改进(8)— 引入GSConv + Slim Neck相结合的方式降低模型复杂性

前言:Hello大家好,我是小哥谈。在文章中,作者提出了一种新方法 GSConv 来减轻模型的复杂度并保持准确性。GSConv可以更好地平衡模型的准确性和速度。并且,提供了一种设计范式Slim Neck,以实现检测器更高的计算成本效益。实验过程中,与原始网络相比,改进方法获得了最优秀…

软件测试/测试开发丨Selenium的常用元素定位方法

Selenium是一个流行的开源框架&#xff0c;目前在 Web 自动化方面运用最为广泛的一个开源、无浏览器要求、可支持多语言、设计测试用例非常灵活的自动化测试框架。支持多种编程语言&#xff0c;并且能够模拟用户操作&#xff0c;例如点击、输入、提交等等。 在Selenium中&…

《深入理解JAVA虚拟机笔记》Java 运行时内存区域

程序计数器&#xff08;线程私有&#xff09; 程序计数器&#xff08;Program Counter Register&#xff09;是一块较小的内存空间&#xff0c;它可以看做是当前线程所执行的字节码的行号指示器。在 Java 虚拟机的概念模型里&#xff0c; 字节码解释器工作时就是通过改变这个计…

【Linux--多线程同步与互斥】

目录 一、线程互斥1.1相关概念介绍1.2互斥量mutex1.3互斥量接口1.3.1初始化互斥量1.3.2销毁互斥量1.3.3互斥量加锁1.3.4互斥量解锁1.3.5使用互斥量解决上面分苹果问题 1.4互斥原理 二、可重入与线程安全2.1相关概念2.2常见线程不安全的情况2.3常见不可重入的情况2.4 可重入与线…

深度解析 | 什么是超融合数据中心网络?

数据中心网络连接数据中心内部通用计算、存储和高性能计算资源&#xff0c;服务器间的所有数据交互都要经由网络转发。当前&#xff0c;IT架构、计算和存储技术都在发生重大变革&#xff0c;驱动数据中心网络从原来的多张网络独立部署向全以太化演进。而传统的以太网无法满足存…

Pycharm引用其他文件夹的py

Pycharm引用其他文件夹的py 方式1&#xff1a;包名设置为Sources ROOT 起包名的时候&#xff0c;需要在该文件夹上&#xff1a;右键 --> Mark Directory as --> Sources ROOT 标记目录为源码目录&#xff0c;就可以了。 再引用就可以了 import common from aoeweb impo…

【C++】开源:cpp-httplib HTTP协议库配置与使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍cpp-httplib HTTP协议库配置与使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&a…