既然你已学习了足够的内容,可以编写更复杂的程序,可能就会在程序中发现不那么简单的缺陷。本章介绍了一些工具和技巧,用于寻找程序中缺陷的根源,
帮助你更快更容易地修复缺陷。程序员之间流传着一个老笑话:“编码占了编程工作量的90%,调试占了另外 90%。”计算机只会做你告诉它做的事情,
它不会读懂你的心思,做你想要它做的事情。即使专业的程序员也一直在制造缺陷,所以如果你的程序有问题,不必感到沮丧。好在,
有一些工具和技巧可以确定你的代码在做什么,以及哪儿出了问题。首先,你要查看日志和断言。这两项功能可以帮助你尽早发现缺陷。一般来说,
缺陷发现的越早,就越容易修复。其次,你要学习如何使用调试器。调试器是 IDLE 的一项功能,它可以一次执行一条指令,在代码运行时,
让你有机会检查变量的值,并追踪程序运行时值的变化。这比程序全速运行要慢得多,但可以帮助你查看程序运行时其中实际的值,
而是通过源代码推测值可能是什么。最后,你还要学习如何使用单元测试。单元测试是一种自动化测试,用于验证你的代码是否按预期工作。
通过编写单元测试,你可以确保你的代码在将来发生变化时仍然按预期工作。

抛出异常

python中,当程序出现错误时,会抛出一个异常。异常是程序运行时出现的问题,例如除以零、文件不存在等。当程序抛出异常时,程序会停止运行,并显示一个错误消息。
raise语句可以用来抛出异常。例如,下面的代码会抛出一个ValueError异常,因为字符串不能被转换为整数:

raise ValueError("字符串不能被转换为整数")

当程序抛出异常时,可以使用try和except语句来捕获异常并处理它。例如,下面的代码会尝试将字符串转换为整数,如果转换失败,会抛出一个ValueError异常,并显示一个错误消息:

try:
    num = int("abc")
except ValueError:
    print("字符串不能被转换为整数")

在上面的代码中,try语句块中的代码会尝试将字符串转换为整数。如果转换失败,会抛出一个ValueError异常,并执行except语句块中的代码,显示一个错误消息。

取得反向跟踪的字符串

Python中的反向跟踪(traceback)是一个用于记录程序运行时错误的工具。当程序出现错误时,Python会自动生成一个反向跟踪字符串,其中包含了错误发生的位置、错误类型和错误消息等信息。

反向跟踪字符串可以帮助开发人员了解程序运行时出现的问题,例如错误发生的位置、错误类型和错误消息等信息。通过查看反向跟踪字符串,开发人员可以快速定位错误发生的位置,并查看错误类型和错误消息,以便更好地理解和修复错误。

日志

Python中的日志模块(logging)是一个用于记录应用程序运行时信息的工具。它可以帮助开发人员了解应用程序的运行状态,发现和修复程序中的错误。

日志模块提供了多种级别的日志记录,包括DEBUG、INFO、WARNING、ERROR和CRITICAL。这些级别表示日志信息的严重程度,从低到高依次为DEBUG、INFO、WARNING、ERROR和CRITICAL。

使用日志模块可以方便地记录应用程序的运行状态,例如记录程序的启动和关闭、记录程序的运行时间、记录程序的错误信息等。这些信息可以帮助开发人员了解应用程序的运行状态,发现和修复程序中的错误。

import logging

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

logging.debug('这是一个调试信息')
logging.info('这是一个信息')
logging.warning('这是一个警告')
logging.error('这是一个错误')
logging.critical('这是一个严重错误')
import logging
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s- %(message)s')
logging.debug('Start of program')
def factorial(n):
 logging.debug('Start of factorial(%s%%)' % (n))
 total = 1
 for i in range(n + 1):
    total *= i
 logging.debug('i is ' + str(i) + ', total is ' + str(total))
 logging.debug('End of factorial(%s%%)' % (n))
 return total
print(factorial(5))
logging.debug('End of program')

输出:
2025-03-19 22:12:52,581 - DEBUG- Start of program
2025-03-19 22:12:52,585 - DEBUG- Start of factorial(5%)
2025-03-19 22:12:52,585 - DEBUG- i is 5, total is 0
2025-03-19 22:12:52,587 - DEBUG- End of factorial(5%)
2025-03-19 22:12:52,590 - DEBUG- End of program
0
通过debug日志 i变量是从0开始的,而不是1 所以total的值是0

import logging
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s- %(message)s')
logging.debug('Start of program')
def factorial(n):
 logging.debug('Start of factorial(%s%%)' % (n))
 total = 1
 for i in range(1,n + 1):
    total *= i
 logging.debug('i is ' + str(i) + ', total is ' + str(total))
 logging.debug('End of factorial(%s%%)' % (n))
 return total
print(factorial(9))
logging.debug('End of program')

2025-03-19 22:17:23,135 - DEBUG- Start of program
2025-03-19 22:17:23,139 - DEBUG- Start of factorial(9%)
2025-03-19 22:17:23,139 - DEBUG- i is 9, total is 362880
2025-03-19 22:17:23,143 - DEBUG- End of factorial(9%)
2025-03-19 22:17:23,149 - DEBUG- End of program
362880

禁用日志

Python中的日志模块(logging)可以用来记录应用程序的运行状态,发现和修复程序中的错误。但是,有时候我们并不需要记录所有的日志信息,只需要记录一些关键的日志信息。在这种情况下,我们可以使用日志模块的级别来控制日志信息的输出。
日志模块提供了多种级别的日志记录,包括DEBUG、INFO、WARNING、ERROR和CRITICAL。这些级别表示日志信息的严重程度,从低到高依次为DEBUG、INFO、WARNING、ERROR和CRITICAL。默认情况下,日志模块的级别为WARNING,这意味着只有WARNING级别及以上的日志信息会被记录。

如果我们想要禁用日志,可以将日志模块的级别设置为CRITICAL,这样只有CRITICAL级别的日志信息会被记录。例如:

import logging
logging.basicConfig(level=logging.CRITICAL, format='%(asctime)s - %(levelname)s - %(message)s')
logging.debug('这是一个调试信息') # 这条日志信息不会被记录
logging.info('这是一个信息') # 这条日志信息不会被记录
logging.warning('这是一个警告') # 这条日志信息不会被记录
logging.error('这是一个错误') # 这条日志信息会被记录
logging.critical('这是一个严重错误') # 这条日志信息会被记录

可以使用 logging.disable(level=logging.CRITICAL) 禁用所有日志

日志文件

Python中的日志模块(logging)可以用来记录应用程序的运行状态,发现和修复程序中的错误。但是,有时候我们并不需要记录所有的日志信息,只需要记录一些关键的日志信息。在这种情况下,我们可以使用日志模块的级别来控制日志信息的输出。
日志模块提供了多种级别的日志记录,包括DEBUG、INFO、WARNING、ERROR和CRITICAL。这些级别表示日志信息的严重程度,从低到高依次为DEBUG、INFO、WARNING、ERROR和CRITICAL。默认情况下,日志模块的级别为WARNING,这意味着只有WARNING级别及以上的日志信息会被记录。
如果我们想要将日志信息输出到文件中,可以使用日志模块的FileHandler类。例如:

import logging

# 创建一个logger
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)

# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('my_log.log')
fh.setLevel(logging.DEBUG)

# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)

# 给logger添加handler
logger.addHandler(fh)

# 记录一条日志
logger.debug('这是一个调试信息')
logger.info('这是一个信息')
logger.warning('这是一个警告')
logger.error('这是一个错误')
logger.critical('这是一个严重错误')

这样,日志信息就会被写入到my_log.log文件中。

IDE 断点调试

练习

  1. 写一条 assert 语句,如果变量 spam 是一个小于 10 的整数,就触发AssertionError。
  2. 编写一条 assert 语句,如果 eggs 和 bacon 包含的字符串彼此相同,而且不论大小写如何,就触发 AssertionError(也就是说'hello' 和 'hello' 被认为相同,
    'goodbye' 和 'GOODbye' 也被认为相同)。
  3. 编写一条 assert 语句,总是触发 AssertionError。
  4. 为了能调用 logging.debug(),程序中必须加入哪两行代码?
  5. 为了让 logging.debug() 将日志消息发送到名为 programLog.txt 的文件中,程序必须加入哪两行代码?
  6. 5 个日志级别是什么?
  7. 你可以加入哪一行代码,禁用程序中所有的日志消息?
  8. 显示同样的消息,为什么使用日志消息比使用 print() 要好?
  9. 调试控制窗口中的 Step、Over 和 Out 按钮有什么区别?
  10. 在点击调试控制窗口中的 Go 按钮后,调试器何时会停下来?
  11. 什么是断点?
  12. 在 IDLE 中,如何在一行代码上设置断点?

实践项目

调试硬币抛掷
下面程序的意图是一个简单的硬币抛掷猜测游戏。玩家有两次猜测机会(这是一个简单的游戏)。但是,程序中有一些缺陷。让程序运行几次,找出缺陷,使该程序能正确运行。

import random
guess = ''
while guess not in ('heads', 'tails'):
 print('Guess the coin toss! Enter heads or tails:')
 guess = input()
toss = random.randint(0, 1) # 0 is tails, 1 is heads
if toss == guess:
 print('You got it!')
else:
 print('Nope! Guess again!')
 guesss = input()
 if toss == guess:
 print('You got it!')
 else:
 print('Nope. You are really bad at this game.')

先做好手头的事情

嗯嗯
好的
收到
分阶段 分范围 分时间

睡觉是很重要的 特别是按时

话单处理

学习 成长 破局 进化 认知提升 赚钱 这些都是大而空的概念。
对,当你想着怎么赚钱时,你是赚不到钱的,除非你开始解决具体问题
不要把注意力放在这些词上面
将你的每天的注意力放在解决一个非常具体的与赚钱相关的问题上,比如小红书的封面怎么优化能提高点击率,
文案怎么修改能提高私域转化率
当你持续在解决一个又一个具体问题时,一切都会慢慢获得,包括认知和赚到钱

posted on 2025-03-03 00:19  Martinl_it  阅读(25)  评论(0)    收藏  举报