不打断点,Python如何Debug?

一、raise 与 try…except

(一) raise

当python试图执行无效代码时,就会抛出异常

我们也可以使用 raise 抛出自己的异常

raise Exception("This is an Exception!")
"""
> 输出:
  File "raiseException.py", line 16, in <module>
    raise Exception("This is an Exception!")
Exception: This is an Exception!
"""

(二) try…except

通常情况我们会把raise定义在一个函数中

调用该函数的代码知道如何处理异常,而不是函数本身

def exemple_excetion(input):
    if input == 1:
        raise Exception("Input is not digital!")
    else:
        pass


def test():
    try:
        exemple_excetion(1)
    except Exception as error:
        print 'An exception happened:' + str(error)

test();
"""
> 输出:
An exception happened:Input is not digital!
"""

(三) 反向追踪

在上一种情况中,我们打印出了错误信息

但是在实际项目中,由于代码层次复杂,我们更希望得到错误信息的精确位置,而不仅仅是错误原因

这时候我们可以可以直接将raise Exception的消息暴露出来,而不是在except中处理他

def a():
    aa()
def aa():
    aaa()
def aaa():
    raise Exception("This is an Exception!")
# a()
"""
> 输出:
Traceback (most recent call last):
  File "raiseException.py", line 44, in <module>
    a()
  File "raiseException.py", line 39, in a
    aa()
  File "raiseException.py", line 41, in aa
    aaa()
  File "raiseException.py", line 43, in aaa
    raise Exception("This is an Exception!")
Exception: This is an Exception!
"""

(四)trackback.format_exc()

只要异常没有被处理,Python就会显示反向追踪,导致程序无法继续运行。

在某些场景,我们希望程序运行并且能够打印出字符串,这时候可以调用trackback.format_exc()函数

import traceback
try:
    raise Exception('This is the error message.')
except:
    errorFile = open('errorInfo.txt', 'w')
    errorFile.write(traceback.format_exc())
    errorFile.close()
    print('The trackback info was written to errorInfo.txt.')
"""
> 产生errorInfo文件并输出:
Traceback (most recent call last):
  File "raiseException.py", line 69, in <module>
    raise Exception('This is the error message.')
Exception: This is the error message.
"""

二、assert(断言)

(一)使用断言

format:assert [Judge conditions], AsserionError

try…raise…except用于处理一些逻辑上的异常

有时候我们会因为自己的疏忽犯了一些明显的低级错误,使用 assert(断言) 能够帮助我们进行完整性检查

door_open = 'open'
assert door_open == 'open', 'the doors need to be "open"'
door_open = 'I am sorry'
assert door_open == 'open', 'the doors need to be "open"'
"""
Traceback (most recent call last):
  File "debugAssert.py", line 19, in <module>
    assert door_open == 'open', 'the doors need to be "open"'
AssertionError: the doors need to be "open
"""

断言会终止程序的运行,因为这些错误往往是程序员的错误,而不是用户的错误

对于一些可以恢复的错误,如文件没找到,或者用户输入错误,请抛出异常

“”"

(二) 禁用断言

python -O [filename.py]

三、logging(日志)

(一)使用日志

  1. 在学习编程初期,我们往往会使用print()来帮助我们调试一些代码,这里已经进入到记录日志的思维啦,一个更好的方法是使用Python为我们提供的logging模块
  2. 在头部加上这两行代码:
import logging
logging.basicConfig(filename='logFile.txt', filemode='w',
                    level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')
  1. 简单解释下
  • filename:要输出的文件(这个参数可以没有,表示直接输出到控制台)
  • filemode:表示使用文件的模式,默认为’a’即添加在既有文本后,这里设置为’w’表示每次运行都要先清空文件再写入
  • level: 表示层级(稍后讲解)
  • format: 输出文本的格式
  1. 使用
import logging
logging.basicConfig(filename='logFile.txt', filemode='w',
                    level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')
logging.debug('Debug error! Debug error!')
# 看到logFile.txt中输出了一句话:
"""
> 2020-06-09 10:50:59,695 - DEBUG - Debug error! Debug error!
"""

(二)日志层级

1. 重要等级

将日志信息输出到文本中,我们还希望能够对这些错误信息进行分类,将其分成不同的重要等级,以便我们在将来可以选择自己想要看的等级进行筛选,或者禁用部分低等级的日志信息。

2.五种层级:

logging模块提供了五种常用层级:(CRITICAL最高,DEBUG最低)

CRITICAL = 50
ERROR = 40
WARNING = 30
INFO = 20
DEBUG = 10

3. 筛选层级

在上一节《使用日志》中,logging.basicConfig(level = logging.DEBUG)

其中level参数用于设置 当前可以显示的最低层级

比如下面的代码:

import logging
logging.basicConfig(filename='logFile.txt', filemode='w',
                    level=logging.INFO, format=' %(asctime)s - %(levelname)s - %(message)s')
logging.debug('Debug error! Debug error!')
logging.info('INFO error! INFO error!)

# 输出结果为
"""
> 2020-06-09 10:50:59,695 - INFO - INFO error! INFO error!
"""

4.不要使用print()

尽管初学的时候使用print()是个不错的选择,但是在项目中并不建议这么使用,
因为当你解决完所有bug之后,你可能要找到之前标注的所有print(),并且将其一一删除。

当我们使用logging,尽管每次需要在模块上方添加两行代码:

import logging
logging.basicConfig(filename='logFile.txt', filemode='w',
                    level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')

看起来很烦,但是很快你会发现这是多么聪明的做法,因为你可以通过logging.desable(logging.CRITICAL)禁用代码中的logging语句。

当然,如果你希望你的用户看到这些消息,那么建议你使用print()。

5.禁用日志

现在你已经知道通过logging.desable(logging.CRITICAL)禁用代码中的logging语句。

现在我们有更高的需求,希望禁用部分logging代码,而不是全部,该怎么办呢?
我们注意到logging.desable(level),level = logging.CRITICAL是作为参数传递进去的,并且在第2小节,我们已经知道CRITICAL是最高层级。这其实说明了,level参数表示禁用level及其以下的所有层级。因为logging.CRITICAL是最高层级,也就禁用了所有日志的输出。

接下去我们使用代码尝试一下:

logging.disable(logging.DEBUG) # Disable the level and below the level below
logging.critical('Critical error! Critical error')
logging.debug('Debug error! Debug error!')
"""
> 输出为:
 2020-06-09 11:15:38,623 - CRITICAL - Critical error! Critical error!
"""
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IMUHERO

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

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

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

打赏作者

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

抵扣说明:

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

余额充值