Python代码调试的几种方法总结

使用 pdb 进行调试

pdb 是 python 自带的一个包,为 python 程序提供了一种交互的源代码调试功能,主要特性包括设置断点、单步调试、进入函数调试、查看当前代码、查看栈片段、动态改变变量的值等。pdb 提供了一些常用的调试命令,详情见表 1。
表 1. pdb 常用命令

2015415163749686.jpg (832×326)

下面结合具体的实例讲述如何使用 pdb 进行调试。
清单 1. 测试代码示例

1

2

3

4

5

6

7

import pdb

 a = "aaa"

 pdb.set_trace()

 b = "bbb"

 c = "ccc"

 final = a + b + c

 print final

开始调试:直接运行脚本,会停留在 pdb.set_trace() 处,选择 n+enter 可以执行当前的 statement。在第一次按下了 n+enter 之后可以直接按 enter 表示重复执行上一条 debug 命令。
清单 2. 利用 pdb 调试

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

[root@rcc-pok-idg-2255 ~]# python epdb1.py

 > /root/epdb1.py(4)?()

 -> b = "bbb"

 (Pdb) n

 > /root/epdb1.py(5)?()

 -> c = "ccc"

 (Pdb)

 > /root/epdb1.py(6)?()

 -> final = a + b + c

 (Pdb) list

 1   import pdb

 2   a = "aaa"

 3   pdb.set_trace()

 4   b = "bbb"

 5   c = "ccc"

 6 -> final = a + b + c

 7   print final

 [EOF]

 (Pdb)

 [EOF]

 (Pdb) n

 > /root/epdb1.py(7)?()

 -> print final

 (Pdb)

退出 debug:使用 quit 或者 q 可以退出当前的 debug,但是 quit 会以一种非常粗鲁的方式退出程序,其结果是直接 crash。
清单 3. 退出 debug

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

[root@rcc-pok-idg-2255 ~]# python epdb1.py

 > /root/epdb1.py(4)?()

 -> b = "bbb"

 (Pdb) n

 > /root/epdb1.py(5)?()

 -> c = "ccc"

 (Pdb) q

 Traceback (most recent call last):

 File "epdb1.py", line 5, in ?

  c = "ccc"

 File "epdb1.py", line 5, in ?

  c = "ccc"

 File "/usr/lib64/python2.4/bdb.py", line 48, in trace_dispatch

  return self.dispatch_line(frame)

 File "/usr/lib64/python2.4/bdb.py", line 67, in dispatch_line

  if self.quitting: raise BdbQuit

 bdb.BdbQuit

打印变量的值:如果需要在调试过程中打印变量的值,可以直接使用 p 加上变量名,但是需要注意的是打印仅仅在当前的 statement 已经被执行了之后才能看到具体的值,否则会报 NameError: < exceptions.NameError … ....> 错误。
清单 4. debug 过程中打印变量

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

[root@rcc-pok-idg-2255 ~]# python epdb1.py

 > /root/epdb1.py(4)?()

 -> b = "bbb"

 (Pdb) n

 > /root/epdb1.py(5)?()

 -> c = "ccc"

 (Pdb) p b

'bbb'

 (Pdb)

'bbb'

 (Pdb) n

 > /root/epdb1.py(6)?()

 -> final = a + b + c

 (Pdb) p c

'ccc'

 (Pdb) p final

 *** NameError: <exceptions.NameError instance at 0x1551b710 >

 (Pdb) n

 > /root/epdb1.py(7)?()

 -> print final

 (Pdb) p final

'aaabbbccc'

 (Pdb)

使用 c 可以停止当前的 debug 使程序继续执行。如果在下面的程序中继续有 set_statement() 的申明,则又会重新进入到 debug 的状态,读者可以在代码 print final 之前再加上 set_trace() 验证。
清单 5. 停止 debug 继续执行程序

1

2

3

4

5

6

7

8

[root@rcc-pok-idg-2255 ~]# python epdb1.py

 > /root/epdb1.py(4)?()

 -> b = "bbb"

 (Pdb) n

 > /root/epdb1.py(5)?()

 -> c = "ccc"

 (Pdb) c

 aaabbbccc

显示代码:在 debug 的时候不一定能记住当前的代码块,如要要查看具体的代码块,则可以通过使用 list 或者 l 命令显示。list 会用箭头 -> 指向当前 debug 的语句。
清单 6. debug 过程中显示代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

[root@rcc-pok-idg-2255 ~]# python epdb1.py

 > /root/epdb1.py(4)?()

 -> b = "bbb"

 (Pdb) list

 1   import pdb

 2   a = "aaa"

 3   pdb.set_trace()

 4 -> b = "bbb"

 5   c = "ccc"

 6   final = a + b + c

 7   pdb.set_trace()

 8   print final

 [EOF]

 (Pdb) c

 > /root/epdb1.py(8)?()

 -> print final

 (Pdb) list

 3   pdb.set_trace()

 4   b = "bbb"

 5   c = "ccc"

 6   final = a + b + c

 7   pdb.set_trace()

 8 -> print final

 [EOF]

 (Pdb)

在使用函数的情况下进行 debug
清单 7. 使用函数的例子

1

2

3

4

5

6

7

8

9

10

11

import pdb

 def combine(s1,s2):   # define subroutine combine, which...

  s3 = s1 + s2 + s1  # sandwiches s2 between copies of s1, ...

  s3 = '"' + s3 +'"'  # encloses it in double quotes,...

  return s3      # and returns it.

 a = "aaa"

 pdb.set_trace()

 b = "bbb"

 c = "ccc"

 final = combine(a,b)

 print final

如果直接使用 n 进行 debug 则到 final=combine(a,b) 这句的时候会将其当做普通的赋值语句处理,进入到 print final。如果想要对函数进行 debug 如何处理呢 ? 可以直接使用 s 进入函数块。函数里面的单步调试与上面的介绍类似。如果不想在函数里单步调试可以在断点处直接按 r 退出到调用的地方。
清单 8. 对函数进行 debug

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

[root@rcc-pok-idg-2255 ~]# python epdb2.py

 > /root/epdb2.py(10)?()

 -> b = "bbb"

 (Pdb) n

 > /root/epdb2.py(11)?()

 -> c = "ccc"

 (Pdb) n

 > /root/epdb2.py(12)?()

 -> final = combine(a,b)

 (Pdb) s

 --Call--

 > /root/epdb2.py(3)combine()

 -> def combine(s1,s2):   # define subroutine combine, which...

 (Pdb) n

 > /root/epdb2.py(4)combine()

 -> s3 = s1 + s2 + s1  # sandwiches s2 between copies of s1, ...

 (Pdb) list

 1   import pdb

 2

 3   def combine(s1,s2):   # define subroutine combine, which...

 4 ->   s3 = s1 + s2 + s1  # sandwiches s2 between copies of s1, ...

 5     s3 = '"' + s3 +'"'  # encloses it in double quotes,...

 6     return s3      # and returns it.

 7

 8   a = "aaa"

 9   pdb.set_trace()

 10   b = "bbb"

 11   c = "ccc"

 (Pdb) n

 > /root/epdb2.py(5)combine()

 -> s3 = '"' + s3 +'"'  # encloses it in double quotes,...

 (Pdb) n

 > /root/epdb2.py(6)combine()

 -> return s3      # and returns it.

 (Pdb) n

 --Return--

 > /root/epdb2.py(6)combine()->'"aaabbbaaa"'

 -> return s3      # and returns it.

 (Pdb) n

 > /root/epdb2.py(13)?()

 -> print final

 (Pdb)

在调试的时候动态改变值 。在调试的时候可以动态改变变量的值,具体如下实例。需要注意的是下面有个错误,原因是 b 已经被赋值了,如果想重新改变 b 的赋值,则应该使用! B。
清单 9. 在调试的时候动态改变值

1

2

3

4

5

6

7

8

9

[root@rcc-pok-idg-2255 ~]# python epdb2.py

 > /root/epdb2.py(10)?()

 -> b = "bbb"

 (Pdb) var = "1234"

 (Pdb) b = "avfe"

 *** The specified object '= "avfe"' is not a function

 or was not found along sys.path.

 (Pdb) !b="afdfd"

 (Pdb)

pdb 调试有个明显的缺陷就是对于多线程,远程调试等支持得不够好,同时没有较为直观的界面显示,不太适合大型的 python 项目。而在较大的 python 项目中,这些调试需求比较常见,因此需要使用更为高级的调试工具。接下来将介绍 PyCharm IDE 的调试方法 .
使用 PyCharm 进行调试

PyCharm 是由 JetBrains 打造的一款 Python IDE,具有语法高亮、Project 管理、代码跳转、智能提示、自动完成、单元测试、版本控制等功能,同时提供了对 Django 开发以及 Google App Engine 的支持。分为个人独立版和商业版,需要 license 支持,也可以获取免费的 30 天试用。试用版本的 Pycharm 可以在官网上下载,下载地址为:http://www.jetbrains.com/pycharm/download/index.html。 PyCharm 同时提供了较为完善的调试功能,支持多线程,远程调试等,可以支持断点设置,单步模式,表达式求值,变量查看等一系列功能。PyCharm IDE 的调试窗口布局如图 1 所示。
图 1. PyCharm IDE 窗口布局

2015415163831052.gif (568×364)

下面结合实例讲述如何利用 PyCharm 进行多线程调试。具体调试所用的代码实例见清单 10。
清单 10. PyCharm 调试代码实例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

__author__ = 'zhangying'

 #!/usr/bin/python

 import thread

 import time

 # Define a function for the thread

 def print_time( threadName, delay):

 count = 0

 while count < 5:

  count += 1

  print "%s: %s" % ( threadName, time.ctime(time.time()) )

 def check_sum(threadName,valueA,valueB):

 print "to calculate the sum of two number her"

 result=sum(valueA,valueB)

 print "the result is" ,result;

 def sum(valueA,valueB):

 if valueA >0 and valueB>0:

  return valueA+valueB

 def readFile(threadName, filename):

 file = open(filename)

 for line in file.xreadlines():

  print line

 try:

 thread.start_new_thread( print_time, ("Thread-1", 2, ) )

 thread.start_new_thread( check_sum, ("Thread-2", 4,5, ) )

 thread.start_new_thread( readFile, ("Thread-3","test.txt",))

 except:

 print "Error: unable to start thread"

 while 1:

 # print "end"

 pass

在调试之前通常需要设置断点,断点可以设置在循环或者条件判断的表达式处或者程序的关键点。设置断点的方法非常简单:在代码编辑框中将光标移动到需要设置断点的行,然后直接按 Ctrl+F8 或者选择菜单"Run"->"Toggle Line Break Point",更为直接的方法是双击代码编辑处左侧边缘,可以看到出现红色的小圆点(如图 2)。当调试开始的时候,当前正在执行的代码会直接显示为蓝色。下图中设置了三个断点,蓝色高亮显示的为正在执行的代码。
图 2. 断点设置

2015415163858070.jpg (555×204)

表达式求值:在调试过程中有的时候需要追踪一些表达式的值来发现程序中的问题,Pycharm 支持表达式求值,可以通过选中该表达式,然后选择“Run”->”Evaluate Expression”,在出现的窗口中直接选择 Evaluate 便可以查看。

Pychar 同时提供了 Variables 和 Watches 窗口,其中调试步骤中所涉及的具体变量的值可以直接在 variable 一栏中查看。
图 3. 变量查看

2015415163926095.jpg (423×115)

如果要动态的监测某个变量可以直接选中该变量并选择菜单”Run”->”Add Watch”添加到 watches 栏中。当调试进行到该变量所在的语句时,在该窗口中可以直接看到该变量的具体值。
图 4. 监测变量

2015415163951352.jpg (278×178)

对于多线程程序来说,通常会有多个线程,当需要 debug 的断点分别设置在不同线程对应的线程体中的时候,通常需要 IDE 有良好的多线程调试功能的支持。 Pycharm 中在主线程启动子线程的时候会自动产生一个 Dummy 开头的名字的虚拟线程,每一个 frame 对应各自的调试帧。如图 5,本实例中一共有四个线程,其中主线程生成了三个线程,分别为 Dummy-4,Dummy-5,Dummy-6. 其中 Dummy-4 对应线程 1,其余分别对应线程 2 和线程 3。
图 5. 多线程窗口

2015415164022485.jpg (306×252)

当调试进入到各个线程的子程序时,Frame 会自动切换到其所对应的 frame,相应的变量栏中也会显示与该过程对应的相关变量,如图 6,直接控制调试按钮,如 setp in,step over 便可以方便的进行调试。
图 6. 子线程调试

2015415164053690.jpg (568×410)

使用 PyDev 进行调试

PyDev 是一个开源的的 plugin,它可以方便的和 Eclipse 集成,提供方便强大的调试功能。同时作为一个优秀的 Python IDE 还提供语法错误提示、源代码编辑助手、Quick Outline、Globals Browser、Hierarchy View、运行等强大功能。下面讲述如何将 PyDev 和 Eclipse 集成。在安装 PyDev 之前,需要先安装 Java 1.4 或更高版本、Eclipse 以及 Python。 第一步:启动 Eclipse,在 Eclipse 菜单栏中找到 Help 栏,选择 Help > Install New Software,并选择 Add button,添加 Ptdev 的下载站点 http://pydev.org/updates。选择 PyDev 之后完成余下的步骤便可以安装 PyDev。
图 7. 安装 PyDev

2015415164129350.jpg (561×453)

安装完成之后需要配置 Python 解释器,在 Eclipse 菜单栏中,选择 Window > Preferences > Pydev > Interpreter – Python。Python 安装在 C:\Python27 路径下。单击 New,选择 Python 解释器 python.exe,打开后显示出一个包含很多复选框的窗口,选择需要加入系统 PYTHONPATH 的路径,单击 OK。
图 8. 配置 PyDev

2015415164223851.jpg (565×507)

在配置完 Pydev 之后,可以通过在 Eclipse 菜单栏中,选择 File > New > Project > Pydev >Pydev Project,单击 Next 创建 Python 项目,下面的内容假设 python 项目已经创建,并且有个需要调试的脚本 remote.py(具体内容如下),它是一个登陆到远程机器上去执行一些命令的脚本,在运行的时候需要传入一些参数,下面将详细讲述如何在调试过程中传入参数 .
清单 11. Pydev 调试示例代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

#!/usr/bin/env python

import os

def telnetdo(HOST=None, USER=None, PASS=None, COMMAND=None): #define a function

import telnetlib, sys

if not HOST:

try:

HOST = sys.argv[1]

USER = sys.argv[2]

PASS = sys.argv[3]

COMMAND = sys.argv[4]

except:

print "Usage: remote.py host user pass command"

return

tn = telnetlib.Telnet() #

try:

tn.open(HOST)

except:

print "Cannot open host"

return

tn.read_until("login:")

tn.write(USER + '\n')

if PASS:

tn.read_until("Password:")

tn.write(PASS + '\n')

tn.write(COMMAND + '\n')

tn.write("exit\n")

tmp = tn.read_all()

tn.close()

del tn

return tmp

if __name__ == '__main__':

print telnetdo()

在调试的时候有些情况需要传入一些参数,在调试之前需要进行相应的配置以便接收所需要的参数,选择需要调试的程序(本例 remote.py),该脚本在 debug 的过程中需要输入四个参数:host,user,password 以及命令。在 eclipse 的工程目录下选择需要 debug 的程序,单击右键,选择“Debug As”->“Debug Configurations”,在 Arguments Tab 页中选择“Variables”。如下 图 9 所示 .
图 9. 配置变量

2015415164245562.gif (551×447)

在窗口”Select Variable”之后选择“Edit Varuables” ,出现如下窗口,在下图中选择”New” 并在弹出的窗口中输入对应的变量名和值。特别需要注意的是在值的后面一定要有空格,不然所有的参数都会被当做第一个参数读入。
图 10. 添加具体变量

2015415164327781.gif (524×300)

按照以上方式依次配置完所有参数,然后在”select variable“窗口中安装参数所需要的顺序依次选择对应的变量。配置完成之后状态如下图 11 所示。
图 11. 完成配置

2015415164403539.jpg (469×159)

选择 Debug 便可以开始程序的调试,调试方法与 eclipse 内置的调试功能的使用相似,并且支持多线程的 debug,这方面的文章已经有很多,读者可以自行搜索阅读,或者参考”使用 Eclipse 平台进行调试“一文。
使用日志功能达到调试的目的

日志信息是软件开发过程中进行调试的一种非常有用的方式,特别是在大型软件开发过程需要很多相关人员进行协作的情况下。开发人员通过在代码中加入一些特定的能够记录软件运行过程中的各种事件信息能够有利于甄别代码中存在的问题。这些信息可能包括时间,描述信息以及错误或者异常发生时候的特定上下文信息。 最原始的 debug 方法是通过在代码中嵌入 print 语句,通过输出一些相关的信息来定位程序的问题。但这种方法有一定的缺陷,正常的程序输出和 debug 信息混合在一起,给分析带来一定困难,当程序调试结束不再需要 debug 输出的时候,通常没有很简单的方法将 print 的信息屏蔽掉或者定位到文件。python 中自带的 logging 模块可以比较方便的解决这些问题,它提供日志功能,将 logger 的 level 分为五个级别,可以通过 Logger.setLevel(lvl) 来设置。默认的级别为 warning。
表 2. 日志的级别

2015415164438205.jpg (811×197)

ogging lib 包含 4 个主要对象

  1.     logger:logger 是程序信息输出的接口。它分散在不同的代码中使得程序可以在运行的时候记录相应的信息,并根据设置的日志级别或 filter 来决定哪些信息需要输出并将这些信息分发到其关联的 handler。常用的方法有 Logger.setLevel(),Logger.addHandler() ,Logger.removeHandler() ,Logger.addFilter() ,Logger.debug(), Logger.info(), Logger.warning(), Logger.error(),getLogger() 等。logger 支持层次继承关系,子 logger 的名称通常是父 logger.name 的方式。如果不创建 logger 的实例,则使用默认的 root logger,通过 logging.getLogger() 或者 logging.getLogger("") 得到 root logger 实例。
  2.     Handler:Handler 用来处理信息的输出,可以将信息输出到控制台,文件或者网络。可以通过 Logger.addHandler() 来给 logger 对象添加 handler,常用的 handler 有 StreamHandler 和 FileHandler 类。StreamHandler 发送错误信息到流,而 FileHandler 类用于向文件输出日志信息,这两个 handler 定义在 logging 的核心模块中。其他的 hander 定义在 logging.handles 模块中,如 HTTPHandler,SocketHandler。
  3.     Formatter:Formatter 则决定了 log 信息的格式 , 格式使用类似于 %(< dictionary key >)s 的形式来定义,如'%(asctime)s - %(levelname)s - %(message)s',支持的 key 可以在 python 自带的文档 LogRecord attributes 中查看。
  4.     Filter:Filter 用来决定哪些信息需要输出。可以被 handler 和 logger 使用,支持层次关系,比如如果设置了 filter 为名称为 A.B 的 logger,则该 logger 和其子 logger 的信息会被输出,如 A.B,A.B.C.

清单 12. 日志使用示例

import logging
 LOG1=logging.getLogger('b.c')
 LOG2=logging.getLogger('d.e')
 filehandler = logging.FileHandler('test.log','a')
 formatter = logging.Formatter('%(name)s %(asctime)s %(levelname)s %(message)s')
 filehandler.setFormatter(formatter)
 filter=logging.Filter('b')
 filehandler.addFilter(filter)
 LOG1.addHandler(filehandler)
 LOG2.addHandler(filehandler)
 LOG1.setLevel(logging.INFO)
 LOG2.setLevel(logging.DEBUG)
 LOG1.debug('it is a debug info for log1')
 LOG1.info('normal infor for log1')
 LOG1.warning('warning info for log1:b.c')
 LOG1.error('error info for log1:abcd')
 LOG1.critical('critical info for log1:not worked')
 LOG2.debug('debug info for log2')
 LOG2.info('normal info for log2')
 LOG2.warning('warning info for log2')
 LOG2.error('error:b.c')
 LOG2.critical('critical')

上例设置了 filter b,则 b.c 为 b 的子 logger,因此满足过滤条件该 logger 相关的日志信息会 被输出,而其他不满足条件的 logger(这里是 d.e)会被过滤掉。
清单 13. 输出结果

b.c 2011-11-25 11:07:29,733 INFO normal infor for log1
 b.c 2011-11-25 11:07:29,733 WARNING warning info for log1:b.c
 b.c 2011-11-25 11:07:29,733 ERROR error info for log1:abcd
 b.c 2011-11-25 11:07:29,733 CRITICAL critical info for log1:not worked

logging 的使用非常简单,同时它是线程安全的,下面结合多线程的例子讲述如何使用 logging 进行 debug。
清单 14. 多线程使用 logging

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

logging.conf

 [loggers]

 keys=root,simpleExample

 [handlers]

 keys=consoleHandler

 [formatters]

 keys=simpleFormatter

 [logger_root]

 level=DEBUG

 handlers=consoleHandler

 [logger_simpleExample]

 level=DEBUG

 handlers=consoleHandler

 qualname=simpleExample

 propagate=0

 [handler_consoleHandler]

 class=StreamHandler

 level=DEBUG

 formatter=simpleFormatter

 args=(sys.stdout,)

 [formatter_simpleFormatter]

 format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

 datefmt=

 code example:

 #!/usr/bin/python

 import thread

 import time

 import logging

 import logging.config

 logging.config.fileConfig('logging.conf')

 # create logger

 logger = logging.getLogger('simpleExample')

 # Define a function for the thread

 def print_time( threadName, delay):

 logger.debug('thread 1 call print_time function body')

 count = 0

 logger.debug('count:%s',count)

总结

全文介绍了 python 中 debug 的几种不同的方式,包括 pdb 模块、利用 PyDev 和 Eclipse 集成进行调试、PyCharm 以及 Debug 日志进行调试,希望能给相关 python 使用者一点参考。更多关于 python debugger 的资料可以参见参考资料。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

互联网加竞赛 基于机器视觉的12306验证码识别

文章目录 0 简介1 数据收集2 识别过程3 网络构建4 数据读取5 模型训练6 加入Dropout层7 数据增强8 迁移学习9 结果9 最后 0 简介 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器视觉的12306验证码识别 该项目较为新颖&#xff0c;适合作为竞赛课题方向…

6.1810: Operating System Engineering 2023 <Lab7 lock: Parallelism/locking>

一、本节任务 二、要点 2.1 文件系统&#xff08;file system&#xff09; xv6 文件系统软件层次如下&#xff1a; 通过路径树我们可以找到相应的文件&#xff1a; fd&#xff08;文件描述符&#xff09;是进程用来标识其打开的文件的手段&#xff0c;每个进程有自己的文件…

程序员有哪些接s单的渠道?

这题我会&#xff01;程序员接单的渠道那可太多了&#xff0c;想要接到合适的单子&#xff0c;筛选一个合适的平台很重要。如果你也在寻找一个合适的接单渠道&#xff0c;可以参考以下这些方向。 首先&#xff0c;程序员要对接单有一个基本的概念&#xff1a;接单渠道可以先粗…

Elasticsearch_8.11.4_kibana_8.11.4_metricbeat_8.11.4安装及本地部署_ELK日志部署

文章目录 Elasticsearch_8.11.4_kibana_8.11.4_metricbeat_8.11.4安装及本地部署_ELK日志部署分布式引擎Elasticsearch_8.11.4安装及本地部署系统环境要求1 Windows 安装 Elasticsearch下载完成后进行解压,进入 bin 目录,找到elasticsearch.bat脚本文件执行一键启动.启动都选允…

51单片机HC-SR04超声波测距lcd1602显示(程序+ad硬件设计+文档说明)

本帖主控使用STC89C52单片机&#xff0c;超声波测距采用HC-SR04模块&#xff0c;包含ad硬件设计和文档。 测距原理 超声波测距是通过不断检测超声波发射后遇到障碍物所反射的回波&#xff0c;从而测出发射和接收回波的时间差t,然后求出距SCt/2,式中的C为超声波波速。由于超声…

环保时代下的品牌全球化之路:绿色供应链的战略洞察

随着全球化的深入和消费者对可持续发展和环保的日益关注&#xff0c;品牌出海不仅需要考虑市场扩张和竞争力提升&#xff0c;还需要认真思考如何在全球供应链中构建绿色可持续的供应链体系。本文Nox聚星将和大家探讨品牌出海的绿色供应链建设&#xff0c;分析可持续发展和环保要…

机器学习扩散模型简介

一、说明 扩散模型的迅速崛起是过去几年机器学习领域最大的发展之一。在这本易于理解的指南中了解您需要了解的有关扩散模型的所有信息。 扩散模型是生成模型&#xff0c;在过去几年中越来越受欢迎&#xff0c;这是有充分理由的。仅在 2020 年代发布的几篇开创性论文就向世界…

MySQL系列之数据导入导出

前言 大数据与云计算作为当今时代&#xff0c;数据要素发展的“动力引擎”&#xff0c;已经走进了社会生活的方方方面。而背后承载的云服务或数据服务的高效运转&#xff0c;起了决定作用。 作为数据存储的重要工具&#xff0c;数据库的品类和特性也日新月异。从树型、网络型…

MySQL/Oracle 的 字符串拼接

目录 MySQL、Oracle 的 字符串拼接1、MySQL 的字符串拼接1.1 CONCAT(str1,str2,...) : 可以拼接多个字符串1.2 CONCAT_WS(separator,str1,str2,...) : 指定分隔符拼接多个字符串1.3 GROUP_CONCAT(expr) : 聚合函数&#xff0c;用于将多行的值连接成一个字符串。 2、Oracle 的字…

C#灵活控制多线程的状态(开始暂停继续取消)

ManualResetEvent类 ManualResetEvent是一个同步基元&#xff0c;用于在多线程环境中协调线程的执行。它提供了两种状态&#xff1a;终止状态和非终止状态。 在终止状态下&#xff0c;ManualResetEvent允许线程继续执行。而在非终止状态下&#xff0c;ManualResetEvent会阻塞线…

Python画球面投影图

天文学研究中&#xff0c;有时候需要画的并不是传统的XYZ坐标系&#xff0c;而是需要画一个形如这样子的球面投影图&#xff1a; 下面讲一下这种图怎么画 1. 首先要安装healpy包 pip install healpy 2. 然后导入包 如果之前安装过healpy&#xff0c;有的会提示不存在healpy…

【蓝桥杯日记】第一篇——如何搭建系统环境

目录 前言 环境相关文件 学生机环境-Web应用开发环境&#xff08;第十五届大赛&#xff09; 学生机环境-Java编程环境&#xff08;第十五届大赛&#xff09; 学生机环境-C/C编程环境&#xff08;第十五届大赛&#xff09; 学生机环境-Python编程环境 &#xff08;第十五届…

20240112让移远mini-PCIE接口的4G模块EC20在Firefly的AIO-3399J开发板的Android11下跑通【DTS部分】

20240112让移远mini-PCIE接口的4G模块EC20在Firefly的AIO-3399J开发板的Android11下跑通【DTS部分】 2024/1/12 16:20 https://blog.csdn.net/u010164190/article/details/79096345 [Android6.0][RK3399] PCIe 接口 4G模块 EC20 调试记录 https://blog.csdn.net/hnjztyx/artic…

【Linux】线程池实现

&#x1f4d7;线程池实现&#xff08;单例模式&#xff09; 1️⃣线程池概念2️⃣线程池代码样例3️⃣部分问题与细节&#x1f538;类成员函数参数列表中隐含的this指针&#x1f538;单例模式&#x1f538;一个失误导致的bug 4️⃣调用线程池完成任务 1️⃣线程池概念 线程池是…

【Linux驱动】设备树中指定中断 | 驱动中获得中断 | 按键中断实验

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux驱动》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f3c0;在设备树中指定中断&#x1f3c0;代码中获得中断&#x1f3c0;按键中断⚽驱动…

闪存剩下内容

1&#xff1a;通过Arduino IDE向闪存文件系统上传文件 1. 下载 Arduino-ESP8266闪存文件插件程序 2&#xff1a;使用闪存文件系统建立功能更加丰富的网络服务器 1&#xff1a;在网页中加载闪存文件系统中的图片、CSS和JavaScript index.html&#xff1a;ESP8266开发板建立的网…

SpringBoot+SSM项目实战 苍穹外卖(12) Apache POI

继续上一节的内容&#xff0c;本节是苍穹外卖后端开发的最后一节&#xff0c;本节学习Apache POI&#xff0c;完成工作台、数据导出功能。 目录 工作台Apache POI入门案例 导出运营数据Excel报表 工作台 工作台是系统运营的数据看板&#xff0c;并提供快捷操作入口&#xff0c…

初识OpenCV

首先你得保证你的虚拟机Ubuntu能上网 可看 http://t.csdnimg.cn/bZs6c 打开终端输入 sudo apt-get install libopencv-dev 回车 输入密码 回车 遇到Y/N 回车 OpenCV在线文档 opencv 文档链接 点zip可以下载&#xff0c;点前面的直接在线浏览&#xff0c;但是很慢 https…

单元测试:Testing leads to failure, and failure leads to understanding

单元测试的概念可能多数读者都有接触过。作为开发人员&#xff0c;我们编写一个个测试用例&#xff0c;测试框架发现这些测试用例&#xff0c;将它们组装成测试 suite 并运行&#xff0c;收集测试报告&#xff0c;并且提供测试基础设施&#xff08;断言、mock、setup 和 teardo…

JAVAEE初阶 文件IO(一)

这里写目录标题 一. 计算机中存储数据的设备1.1 CPU1.2 内存1.3 硬盘1.4 三种存储的区别 二.文件系统2.1 相对路径2.2 绝对路径2.3 .和..的含义2.4 例子2.5 everything工具 三.文件3.1 文本文件3.2 二进制文件 四. JAVA对于文件的API4.1 getParent getName getPath getAbsolute…