万字长文 - Python 日志记录器logging 百科全书 之 基础配置

在这里插入图片描述

万字长文 - Python 日志记录器logging 百科全书 之 基础配置

前言

在日常的开发中工作中,日志记录扮演着不可或缺的角色。它不仅能让我们了解应用程序的运行状况,还能帮助我们定位并解决各种问题。

  • 最基本的,它记录了应用程序的运行情况,我们可以从日志文件中了解到程序的运行的基本信息;

  • 其次,当应用程序奔溃时,我们可以从日志文件中快速定位到应用程序崩溃前的状态,帮助我们找出问题所在;

  • 或者,应用程序的某些功能表现不佳,日志可以帮助我们找到性能瓶颈,从而进行调优。

总而言之,日志记录可以帮助我们快速定位并解决程序中的错误,实时监控系统运行状态,及时发现并处理问题。

在这篇文章中,我将介绍 Pythonlogging 模块,它是一个Python标准库。

它可以帮助我们完成应用程序生命周期中的所有的日志记录任务。让我们踏上这个旅程吧!

念念碎🎊🎊

本意是分享关于一篇Python中的logging模块的日志记录功能。

文章标题也都命名好了,就叫 《万字长文 - Python 日志记录器logging 百科全书》

但是在文章的编写的过程中我发现,单单是关于基础配置已经超10000字数了。

全文写完的话,估计得5w+字数吧,文章太长就不方便查阅啦!

所以我就做了拆分,这里是第一篇。关于logging的基础配置!

后面还会有:

  • 日志回滚
  • 高级配置
  • 日志过滤
  • 日志处理器
  • 性能优化

等等知识点,感兴趣的读者朋友们可以一起学习哦!


知识点📖📖

模块释义
loggingPython 的日志记录工具,标准库

导入模块

import logging

官方示例

官方示例:日志指南 — Python 3.12.0 文档

我们先来从一个官方的示例入手,逐步来为读者朋友们介绍logging

记录日志到文件

import logging# 基础配置
logging.basicConfig(filename='example.log', encoding='utf-8', level=logging.DEBUG)# 记录不同级别的日志
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
logging.error('And non-ASCII stuff, too, like Øresund and Malmö')

在这个例子中,首先导入了logging模块;

并使用logging.basicConfig函数来进行基本配置。这是配置日志系统的最简单方式。在这个示例中,指定了三个关键参数:

  • filename='example.log':这告诉logging模块将日志消息写入到example.log文件中。
  • encoding='utf-8':这确保了即使日志消息包含非ASCII字符(如“Øresund”和“Malmö”)也能被正确记录。
  • level=logging.DEBUG:这设置了日志级别为DEBUG,意味着所有级别(DEBUG, INFO, WARNING, ERROR, CRITICAL)的日志都会被记录。

下面是关官方文档对于logging的一些方法的注解:

  • 对于简单的日志使用来说日志功能提供了一系列便利的函数。它们是 debug()info()warning()error()critical()。(可以理解为是另一种print,也是作用于打印)
你想要执行的任务此任务最好的工具
对于命令行或程序的应用,结果显示在控制台。print()
在对程序的普通操作发生时提交事件报告(比如:状态监控和错误调查)logging.info() 函数(当有诊断目的需要详细输出信息时使用 logging.debug() 函数)
提出一个警告信息基于一个特殊的运行时事件warnings.warn() 位于代码库中,该事件是可以避免的,需要修改客户端应用以消除告警logging.warning() 不需要修改客户端应用,但是该事件还是需要引起关注
对一个特殊的运行时事件报告错误引发异常
报告错误而不引发异常(如在长时间运行中的服务端进程的错误处理)logging.error(), logging.exception()logging.critical() 分别适用于特定的错误及应用领域

不出意外的话,你会在example.log的日志文件中看到以下日志信息:

在这里插入图片描述

基础配置

在进行日志记录时候,需要考虑的是如何配置日志。这包括定义日志文件的名称、格式,以及确定记录哪些级别的日志信息等。

在前面 官方示例 ,初步接触到了logging的基础配置和日志级别,在这里做详细介绍。

basicConfig

值得注意的是,basicConfig() 在程序运行期间只应被调用一次,通常是在程序的开始处定义。但不管调用多少次,只有第一次的调用会生效,后续的调用将被忽略。

先来看 basicConfig(基础配置)

basicConfiglogging模块的一个方法,下面 logging.basicConfig() 函数的主要配置参数及其描述。

参数描述示例值/备注
filename指定一个文件来保存日志。'myapp.log'
filemode指定日志文件的打开模式。'a'(追加模式)、'w'(写模式)
format定义日志消息的格式。'%(asctime)s - %(levelname)s - %(message)s'
datefmt定义时间格式(用于 format 中的 %(asctime)s)。'%Y-%m-%d %H:%M:%S'
style决定 format 字符串的风格。'%'(默认)、'{''$'
level设置日志的基本级别。logging.INFO, logging.DEBUG, 等
stream指定日志消息的输出流。sys.stdout, sys.stderr
handlers指定一个或多个日志处理器,而不是使用 filenamefilemode[logging.FileHandler('filename'), logging.StreamHandler()]
force强制覆盖任何已经存在的日志配置(Python 3.8+)。TrueFalse
encoding指定文件的编码方式(仅当 filename 被使用时)。'utf-8', 'ascii'
errors指定如何处理编码错误(仅当 filename 被使用时)。'strict', 'replace', 'ignore'

一个简单的 basicConfig 使用示例可能是这样的:

  • 在这个示例中,日志级别被设置为 INFO,模式为W 写模式(即覆盖)。日志格式包括时间戳、日志级别和消息内容。日志会被写入到 app.log 文件中。
import logging# 基础配置
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(message)s',datefmt='%Y-%m-%d %H:%M:%S',filename='example.log',filemode='w',errors='ignore')# 记录不同级别的日志
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
logging.error('And non-ASCII stuff, too, like Øresund and Malmö')

修改一下上面的 官方示例 的代码,将basicConfig的配置替换。如果没有意外的话,你会在example.log的日志文件中看到以下日志信息:

在这里插入图片描述

如果你足够细心,你会有以下发现:

  • 这里的日志内容值有3行,相比上面的 官方示例 的日志内容少了1行;
  • 日志内容带有时间,且内容以 - 做分隔;
  • 非ASCII字符不见了。

这里涉及到三个参数,对应上面的三个变化:

  1. 日志级别
  2. 格式设置
  3. 错误处理

下面分别来介绍一下这 三个变化三个参数

日志级别

基于日志的内容和重要性,我们通常需要设定不同的日志级别。

Python的logging模块提供了强大的日志记录功能,包括五个日志级别:DEBUG、INFO、WARNING、ERROR和CRITICAL。通过设置不同的日志级别,我们可以控制日志输出的详细程度。

日志功能应以所追踪事件级别或严重性而定。各级别适用性如下(以严重性递增):

  • 这份表格是 官方文档 拿下来的,我添加了一列使用场景

logging默认的级别是 WARNING,意味着只会追踪该级别及以上的事件,除非更改日志配置。

级别数值含义 / 何时使用使用场景
logging.NOTSET0当在日志记录器上设置时,表示将查询上级日志记录器以确定生效的级别。 如果仍被解析为 NOTSET,则会记录所有事件。 在处理句柄上设置时,所有事件都将被处理。一般不直接使用,用于继承父级日志记录器的级别或允许记录所有事件。
logging.DEBUG10详细的信息,通常只有试图诊断问题的开发人员才会感兴趣。用于开发阶段,用于详细追踪事件、变量值,帮助诊断问题。
logging.INFO20确认程序按预期运行。用于生产环境,记录常规操作,如程序启动、运行状态或处理流程。
logging.WARNING30表明发生了意外情况,或近期有可能发生问题(例如‘磁盘空间不足’)。 软件仍会按预期工作。用于警告可能会影响程序性能但不影响程序继续运行的问题。
logging.ERROR40由于严重的问题,程序的某些功能已经不能正常执行用于记录程序运行中出现的错误,这些错误会影响某些功能的执行。
logging.CRITICAL50严重的错误,表明程序已不能继续执行用于记录严重错误,如程序崩溃、关键服务失效,需要立即关注的问题。

这些日志级别之间的关系是层级的,也就是说,在设置为某个级别时,会记录该级别以及更高级别的日志。例如,如果日志级别设置为 WARNING,则会记录 WARNINGERRORCRITICAL 级别的消息,但不会记录 DEBUGINFO 级别的消息。

可以理解为,每个级别都包含了比它更高级别的日志信息,而忽略了比它更低级别的信息。所以,选择合适的日志级别可以帮助你筛选出最关心的信息,而忽略不那么重要的细节。


以下是在日常开发或者生产环境中,对应场景建议使用的日志级别。

环境推荐日志级别理由
生产环境INFOWARNING关注程序正常运行和潜在问题,INFO 记录正常操作,WARNING 提示可能的问题但不影响运行。
测试环境DEBUGINFODEBUG 提供详细信息以诊断问题,INFO 提供较少但重要的信息。适用于测试和问题排查。
日常开发DEBUGINFODEBUG 适用于详细追踪和开发阶段,INFO 用于较稳定或需关注主要操作的情况。

以上提供了一个基本的指导,帮助读者朋友们根据不同的应用场景选择合适的日志级别。

然而,具体使用哪个级别还需要根据你的具体需求和项目的复杂度来决定。在实际应用中,需要根据实际情况做出调整。甚至可以在不同阶段动态调整日志级别以满足特定需求。

选择适当的级别有助于确保日志既提供了足够的信息以监控应用程序,又可以避免过多的冗余信息。


解释:日志内容为什么少了一行?

  • 因为 basicConfig 代码中日志级别设置为INFO,所以只记录INFOWARNINGERRORCRITICAL 级别的日志信息,
  • basicConfig 较比 官方示例 的日志级别少了DEBUG,于是内容就少了一行。

格式设置

如果想使用不同的风格,则需要相应地修改 format 字符串,并设置 style 参数。

style

在 Python 的 logging 模块中,style 参数用于指定 format 字符串的风格。这允许选择不同的字符串格式化方法。有三种风格可供选择:

  1. '%' 风格:这是默认的格式化风格,使用传统的 printf 风格的格式化字符串。例如:'%(asctime)s - %(levelname)s - %(message)s'

  2. '{' 风格:使用 str.format() 方法的格式化字符串。例如:'{asctime} - {levelname} - {message}'

  3. '$' 风格:使用 string.Template 风格的格式化字符串。例如:'${asctime} - ${levelname} - ${message}'

根据自己选择的 style,我们需要相应地调整 format 参数中的字符串,否则会抛出 ValueError 异常。

选择哪种风格主要取决于个人偏好以及项目中已有的编码风格。'%' 风格是最传统的,而 '{''$' 提供了更现代和灵活的字符串格式化选项(但他们记录的内容是一致的)。

示例的配置如下所示:

  • 使用 '%' 风格:

    logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(message)s',style='%')
    
  • 使用 '{' 风格:

    logging.basicConfig(level=logging.INFO,format='{asctime} - {levelname} - {message}',style='{')
    
  • 使用 '$' 风格:

    logging.basicConfig(level=logging.INFO,format='${asctime} - ${levelname} - ${message}',style='$')
    

在 Python logging 模块中,format 字符串可以包含多种格式化字段,这些字段用于定义日志消息的具体内容。以下是一些常用的格式化字段,以表格形式展示:

格式化字段描述
%(name)sLogger 的名字(即创建 Logger 实例时指定的名称)
%(levelno)s日志级别的数值表示(如 10, 20, 30, …)
%(levelname)s日志级别的文本表示(如 ‘DEBUG’, ‘INFO’, ‘WARNING’, 等)
%(pathname)s调用日志记录函数的源码文件的全路径
%(filename)spathname 的文件名部分
%(module)sfilename 的模块名部分
%(funcName)s调用日志记录函数的函数名
%(lineno)d调用日志记录函数的源代码行号
%(asctime)s创建日志记录的时间。默认格式为 ‘2023-11-07 09:13:45,896’
%(thread)d线程ID
%(threadName)s线程名
%(process)d进程ID
%(message)s日志消息本身

我们可以根据需要在 format 字符串中组合使用这些字段。例如:

  • 这个配置会产生包含时间戳、Logger 名称、日志级别和消息本身的日志记录。
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

常用配置:

在 Python logging 中,最常用的 format 字段取决于项目的日志需求和个人偏好,以下是一些被频繁使用的字段:

  1. %(asctime)s:显示日志事件发生的时间。这是非常有用的信息,因为它帮助我们知道什么时候发生了什么事件;
  2. %(levelname)s:显示日志消息的级别(如 DEBUG, INFO, WARNING, ERROR, CRITICAL)。这是不可或缺的;
  3. %(message)s:显示日志消息本身。这是日志记录的核心部分,包含了事件或数据的实际描述。
  4. %(name)s:显示 Logger 的名字。如果在一个大型应用中使用多个 logger,这可以帮助我们确定哪个 logger 产生了消息。
  5. %(filename)s%(lineno)d:这些字段显示产生日志消息的源文件名和行号。在调试时,它们能帮助我们快速定位问题所在的代码位置。

一个典型的 format 配置可能是这样的:

logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s')

这个配置提供了日志消息的时间、来源、级别、位置(文件和行号)和具体内容,适用于大多数常规日志记录需求。但具体的配置还是需要根据项目需求和你的具体情况,选择添加或省略某些字段。


解释:日志内容带有时间

  • 因为代码中使用了 format='%(asctime)s - %(levelname)s - %(message)s'

错误处理

指定如何处理编码错误(仅当 filename 被使用时生效)

在 Python 的 logging 模块中,errors 参数是用于配置日志文件写入时的错误处理策略。这个参数仅在使用 filename 参数(即将日志写入到文件)时有效,并且通常与 encoding 参数一起使用。errors 参数定义了在写入日志文件时如何处理那些无法根据指定的编码(如 UTF-8)编码的字符。

以下是几种常见的 errors 参数配置选项及其含义:

  1. 'strict':这是默认的错误处理方式。如果遇到无法按照指定编码的字符,会引发 UnicodeEncodeError 异常,导致日志记录中断;

  2. 'ignore':忽略无法编码的字符。这意味着那些无法编码的字符将被静默地从日志消息中删除,而不会抛出异常;

  3. 'replace':用一个替代字符(通常是 '?')来替换无法编码的字符。这种方式可以避免编码错误的异常,同时保留了无法编码字符的占位符,从而使你知道在原始消息中存在某些问题;

  4. 'backslashreplace':用 Python 的反斜杠转义序列来替换无法编码的字符。这种方式在保持日志可读性的同时,提供了关于原始字符的更多信息;

  5. 'xmlcharrefreplace':用适合于 XML 和 HTML 的字符引用来替换无法编码的字符。

例如,如果我们希望在写入日志文件时避免因为编码错误而中断日志记录,可以选择使用 'replace''ignore'

logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(message)s',filename='example.log',filemode='w',encoding='utf-8',errors='replace')

在这个例子中,任何无法按照 UTF-8 编码的字符都会被 '?' 替换,从而保证日志记录的连续性。这种配置对于多语言环境或处理包含特殊字符的数据时尤其有用。


解释:非ASCII字符不见了

  • errors设置为**ignore**,则会忽略非ASCII字符

示例代码🎈🎈

一般

这个示例包括了日志的基本设置,如日志级别、格式、文件名等,以及如何在代码中使用不同级别的日志记录。

在具体的使用时候,我们只需要在应用程序中将对应的logging.debug、logging.info…等方法记录日志即可。

import logging# 基础配置
logging.basicConfig(level=logging.INFO,  # 设置日志级别为INFOformat='%(asctime)s - %(name)s - %(levelname)s - %(message)s',  # 设置日志格式datefmt='%Y-%m-%d %H:%M:%S',  # 设置时间格式filename='app.log',  # 日志输出到app.log文件filemode='w',  # 写入模式encoding='utf-8',  # 文件编码errors='ignore'  # 忽略编码错误
)# 记录不同级别的日志
logging.debug('Debug message')  # 通常用于详细的系统诊断信息
logging.info('Info message')  # 通常用于记录程序运行状态或操作
logging.warning('Warning message')  # 用于警告信息,可能的问题
logging.error('Error message')  # 用于记录错误事件
logging.critical('Critical message')  # 用于记录严重的错误事件,可能导致程序终止

高级

进一步的,应用程序在运行时候,特别是在复杂的应用程序中,可能无法预见所有可能的错误场景。这个时候,最好的做法是让程序能够优雅地终止或继续运行。

在下面的示例中:

  • setup_logging 函数配置了基础的日志记录设置。
  • handle_exception 作为全局异常处理器,用于捕获未被局部 try-except 块捕获的异常,并使用 logging 记录异常信息。
  • my_function 演示了日志记录的常规用法,包括记录操作开始的信息和捕获处理异常的情况。
  • 通过 sys.excepthook 设置了自定义的全局异常处理函数。

handle_exception 作为全局异常处理器,负责捕获并处理整个程序中未被其他 try-except 块捕获的异常。函数解释如下:

  • 对于所有其他类型的异常,函数使用 logging.error 来记录异常信息。exc_info 参数被设置为一个包含异常类型、值和回溯信息的元组,这样 logging 模块可以记录完整的异常堆栈信息。

这样,即使在 my_function 中抛出的除以零异常没有被显式捕获,全局异常处理器也会捕获它,并将相关信息记录到日志文件中。

import logging
import sysdef setup_logging():logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(message)s',datefmt='%Y-%m-%d %H:%M:%S',filename='app.log',filemode='w',encoding='utf-8',errors='ignore')def handle_exception(exc_type, exc_value, exc_traceback):"""全局异常处理函数,用于捕获并处理所有未被捕获的异常。Args:exc_type: 异常的类型,例如 ZeroDivisionErrorexc_value: 异常实例,包含异常消息等信息。exc_traceback: 一个 traceback 对象,包含异常发生时的调用堆栈信息。Returns:"""# 使用 logging 记录异常信息logging.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))def my_function():# 潜在的异常操作result = 10 / 0return resultif __name__ == '__main__':setup_logging()sys.excepthook = handle_exception# 运行示例函数my_function()

使用场景和注意事项

handle_exception 作为全局异常处理器,用于捕获那些在程序的其他部分未被明确捕获的异常。在使用这个全局异常处理器时,应注意:

  • 它不应替代在函数或方法内部对特定异常的具体处理。对于已知可能发生的异常,应在相应的代码区域内使用 try-except 块进行处理。
  • 这个处理器更适合用于捕获意外异常,记录异常信息,并在可能的情况下让程序能够优雅地终止或继续运行。

总结🎞🎞

在这篇文章中,我们介绍了 Python 的 logging 模块,这是一个非常强大且灵活的日志记录工具,是 Python 标准库的一部分。通过合理配置和使用 logging 模块,我们可以有效地记录程序的运行情况,监控系统状态,并在必要时定位和解决问题。

我们讨论了 logging 的基础配置,如 basicConfig 方法,以及如何设置日志级别、格式和输出目的地等。我们还探讨了不同日志级别的适用场景,以及如何根据开发环境、测试环境或生产环境选择合适的日志级别。

此外,我们解释了格式化日志消息的不同风格,如 % 风格、{} 风格和 $ 风格,并展示了如何根据个人喜好和项目需求选择合适的风格。我们还讨论了 errors 参数在处理非 ASCII 字符时的重要性,以及如何配置它以避免编码问题。

总之,合理使用 logging 模块能够极大地提升程序的可维护性和可靠性。通过定制化的日志记录策略,我们可以确保在需要时总能获取到足够的信息,以便快速响应和解决任何问题。

后话

本次分享到此结束,

see you~~🐱‍🏍🐱‍🏍

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

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

相关文章

SBCFormer:快速、轻量级神经网络 for 边缘AI

一: SBCFormer [ PDF] SBCFormer 是一种 CNN-ViT 轻量混合网络backbone,能在单板计算机上能以每秒 1 帧速度进行全尺寸 ImageNet 分类的轻量级网络。 通过在低端 CPU 上实现高准确性和快速计算,为树莓派 4 型号 B 的 ARM-Cortex A72 CPU 提供…

情感分析与LLMs角色扮演

深度学习自然语言处理 原创作者:wkk 就像人类在做一件事情的时候,可能需要尝试多次。LLM也是如此!这对于情感分析任务尤其如此,在情感分析任务中,LLM需要深入推理来处理输入中的复杂语言现象(例如&#xff…

「Qt Widget中文示例指南」如何模拟一个时钟?

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。 点击获取Qt Widget组…

康耐视深度学习ViDi-ViDi四大工具之一蓝色定位工具/Locate

目录 工具介绍使用步骤说明调整工具ROI添加特征标签生成定位姿态训练并审核模型编辑器参数说明蓝色定位工具/Locate工具 工具介绍 蓝色定位工具用于识别和定位图像中的特定特征或特征组。该工具的输出可用于为其他ViDi 工具提供位置数据。使用该工具时,您提供图像训练集,然后…

Apache Doris (五十二): Doris Join类型 - Broadcast Join

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录 1. Broadcast Join原理

Vue+OpenLayers 创建地图并显示鼠标所在经纬度

1、效果 2、创建地图 本文用的是高德地图 页面 <div class"map" id"map"></div><div id"mouse-position" class"position_coordinate"></div>初始化地图 var gaodeLayer new TileLayer({title: "高德地…

python数据分析及可视化(十五)数据分析可视化实战篇(抖音用户数据分析、二手房数据分析)

python数据分析的实战篇&#xff0c;围绕实例的数据展开分析&#xff0c;通过数据操作案例来了解数据分析中的频繁用到的知识内容。 抖音用户数据分析 1.理解数据 数据字段含义 了解数据内容&#xff0c;确保数据来源是正常的&#xff0c;安全合法的。理解一下每一个字段的…

C站你好,和你相遇的第1825天

文章目录 机缘收获日常成就憧憬 机缘 ①. 你好,C站 ②. 初识JAVA编程,遇到问题,粘贴问题百度搜索,大都数出来的解决方案都能在C站得到解决,对C站有一定的好感 ③. 起初在CSDN写博客,主要用来记录日常学习过程中的笔记、不断调整自己的笔记,如JAVA基础、框架、虚拟机等,为后…

java传base64返回给数据报404踩坑

一、问题复现 1.可能因为base64字符太长&#xff0c;导致后端处理时出错&#xff0c;表现为前端请求报400错误&#xff1b; 这一步debug进去发现base64数据是正常传值的 所以排除掉不是后端问题,但是看了下前端请求,猜测可能是转换base64时间太长数据过大导致的404 2.前端传…

聚观早报 |GPT-4周活用户数达1亿;长城汽车10月销量增加

【聚观365】11月8日消息 GPT-4周活用户数达1亿 长城汽车10月销量增加 xAI宣布推出PromptIDE工具 aigo爱国者连发5款儿童手表 SpaceX预计今年营收90亿美元 GPT-4周活用户数达1亿 在OpenAI首届开发者大会上&#xff0c;该公司首席执行官萨姆奥特曼&#xff08;Sam Altman&a…

删除word最后一页之后的空白页

最近编辑word比较多&#xff0c;有时最后一页&#xff08;最后一页内容还有可能是表格&#xff09;之后&#xff0c;还有一页空白页&#xff0c;单独按下backspace、del都删不掉&#xff0c;很让人着急。 经过查询有几种方法&#xff1a; &#xff08;1&#xff09;点击选中空…

C#中基于.NET6的动态编译技术

前几天要解决动态计算问题&#xff0c;尝试着使用了不同的方法。问题是给定一个包含计算的字符串&#xff0c;在程序运行中得到计算结果&#xff0c;当时考虑了动态编译&#xff0c;在网上查了一些资料完成了这项功能&#xff0c;可是基于不同的.NET平台使用的编程代码相差比较…

Spring Data JPA 项目配置与QueryDSL集成

一、说明 Spring Data JPA通过Spring Initializer创建时勾选相关依赖即可引入&#xff0c;QueryDSL需要单独引入。Spring JPA针对QueryDSL有比较好的兼容性&#xff0c;可以实现优雅的SQL构建。 二、设置JPA默认配置&#xff08;yaml格式&#xff09; spring:jpa:hibernate:…

【Linux】:使用git命令行 || 在github创建项目 || Linux第一个小程序——进度条(进阶版本)

在本章开始之前还是先给大家分享一张图片 这是C的笔试题 感兴趣的同学可以去试一试 有难度的哟 也可以直接在牛客网直接搜索这几道题目哈 好了今天我们正式进入我们的正题部分 &#x1f556;1.使用git命令行 安装git yum install git&#x1f560;2.在github创建项目 使用…

各省市90米分辨率DEM数据,多图可下载

之前给大家推了30米分辨率dem数据&#xff0c;有些小伙伴反应也需要90米的&#xff0c;于是今天就给大家推荐一个新数据 —— 各省市90米分辨率DEM数据&#xff01; 各省市90米分辨率DEM数据广泛应用于国土资源调查、水利水电工程、地质灾害预警、城市规划等领域&#xff0c;对…

10道高频Vuex面试题快问快答

※其他的快问快答&#xff0c;看这里&#xff01; 10道高频Qiankun微前端面试题快问快答 10道高频webpack面试题快问快答 20道高频CSS面试题快问快答 20道高频JavaScript面试题快问快答 30道高频Vue面试题快问快答 面试中的快问快答 快问快答的情景在面试中非常常见。 在面试过…

公开IP属地信息如何保护用户的隐私?

公开IP属地信息通常涉及与用户或组织的隐私有关&#xff0c;因此在公开此类信息时需要非常小心&#xff0c;以避免侵犯他人的隐私权。以下是触碰底线的几种情况以及如何保护网络安全和用户隐私&#xff1a; 个人隐私保护&#xff1a; 公开IP属地信息可能泄露用户的物理位置&…

响应式编程-Project Reactor Mono 介绍

响应式编程-Project Reactor Mono 介绍 本文以Mono的角度来介绍Reactor编程&#xff0c;Flux的使用同理。 初体验 Web应用 controller 方法在Spring webmvc 和 Spring webFlux下Controller方法实现示例如下&#xff1a; Spring webmvc: GetMapping("/test1") …

最新Cocos Creator 3.x 如何动态修改3D物体的透明度

Cocos Creator 3.x 的2D UI有个组件UIOpacity组件可以动态修改UI的透明度,非常方便。很多同学想3D物体上也有一个这样的组件来动态的控制与修改3D物体的透明度。今天基于Cocos Creator 3.8 来实现一个可以动态修改3D物体透明度的组件Opacity3D。 对啦&#xff01;这里有个游戏…

【深度神经网络(DNN)】实现车牌识别

文章目录 前言一、数据集介绍二、步骤1.导包2.参数配置3.数据处理4.模型定义5.模型训练6.模型预测 总结 前言 课内实践作业 车牌识别 一、数据集介绍 1.车牌识别数据集&#xff1a;VehicleLicense车牌识别数据集包含16151张单字符数据&#xff0c;所有的单字符均为严格切割且…