Python3学习笔记_E(异常、调试)


笔记中代码均可运行在Jupyter NoteBook下(实际上Jupyter-lab使用体验也很棒)。

建议不要光看,要多动手敲代码。眼过千遭,不如手读一遍。

相关笔记的jupiter运行代码已经上传,请在资源中自行下载。

错误和异常

'''
try: # 在try中的异常后的代码不会执行,程序会跳转到except中对异常进行处理
    pass # 需要捕获异常的代码块
except ExceptName as result: # 捕获异常ExceptName并将异常重命名为result
    pass # 对捕获异常的处理代码块
[
except Exp1 as result1: # except 捕获语句可以有多条,不冲突即可
    pass
...
]

Exception :是异常总和,所有异常都可被此异常捕获

当捕获的异常和设定的异常名称不对应时,会进行系统异常处理。

try: # 开启捕获
    pass
except Exp: # 捕获到异常时执行
    pass
else: # 没有捕获到异常时执行
    pass
finally: # 收尾工作,不论是否捕获到异常都会执行
    pass
'''

捕获多个异常

'''
将异常名放入元组中存储
try:
    pass
except (err1, err2 [,err...]):
    pass
'''
# 异常 多个异常 例子
try:
    1/0
    open("sss0")
except NameError:
    print("try中出现NameError的异常")
except Exception as result:
    print("这里出现一个笼统的异常,{}".format(result))
else:
    print("try中没有异常时打印")
finally:
    print("不管try中是否有异常,都会执行finally")
print("异常测试结束")
# 例子结束
这里出现一个笼统的异常,division by zero
不管try中是否有异常,都会执行finally
异常测试结束

异常的嵌套

'''
内部try未捕获到异常,向外部逐层传递
try:
    try:
        pass
    except Exp1:
        pass
    pass
except Exp2:
    pass
'''

自定义异常

'''raise'''

# 用户自定义异常例子
class UserError(Exception):
    def __init__(self):
        print("这里是用户自定义的异常")
try:
    raise UserError
except UserError:
        print("抛出自定义异常")
else:
     print("没有异常")
# 例子结束
这里是用户自定义的异常
抛出自定义异常

异常处理中抛出异常

'''
try:
    Error
except exception as result:
    if (pass):
        pass # 开启捕获异常
        print(result)
    else:
        pass # 重写抛出异常,此时的异常不会被捕获,交由系统处理
        raise
'''

调试

print

最简单

断言(assert)

在程序中可以用print的地方就可以用断言(assert)

assert expression, throwException

表达式expression应该为True,否则,抛出AssertionError:throwException

python -O fileName.py 关闭断言

# assert 例子
def judger(name):
    # name!='username'为True,继续运行,False抛出your name is error!异常
    assert name != 'username','your name is error!'
    print('123456')
    
def main():
    judger('username')
    
if __name__=='__main__':
    main()
    
---------------------------------------------------------------------------

AssertionError                            Traceback (most recent call last)

<ipython-input-1-4fda0f972b48> in <module>()
      9 
     10 if __name__=='__main__':
---> 11     main()
     12 


<ipython-input-1-4fda0f972b48> in main()
      6 
      7 def main():
----> 8     judger('username')
      9 
     10 if __name__=='__main__':


<ipython-input-1-4fda0f972b48> in judger(name)
      2 def judger(name):
      3     # name!='username'为True,继续运行,False抛出your name is error!异常
----> 4     assert name != 'username','your name is error!'
      5     print('123456')
      6 


AssertionError: your name is error!
logging

这篇文章对常用模块总结的很好,有所参照。导向链接

地址:https://www.cnblogs.com/wf-linux/archive/2018/08/01/9400354.html

logging 不会抛出异常,可以把调试信息输出到文件

logging 还可以指定记录信息级别(debug, info, warning, error)

指定level = INFO时,logging.debug就失效,其他级别设定同理。

logging可以通过简单的配置,一条语句同时输出到不同地方,比如:console和文件。

import logging

logging.basicConfig(level=[INFO,DEBUG,WARNING,ERROR,CRITICAL],
                               filename="your_log_file_name",
                               filemode='r,w,a',
                               format='your_log_format')

参数解释:

level:日志记录级别
filename:日志文件
filemode:日志文件的打开模式
format:日志记录格式

参数:作用
%(levelno)s:打印日志级别的数值
%(levelname)s:打印日志级别的名称
%(pathname)s:打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s:打印当前执行程序名
%(funcName)s:打印日志的当前函数
%(lineno)d:打印日志的当前行号
%(asctime)s:打印日志的时间
%(thread)d:打印线程ID
%(threadName)s:打印线程名称
%(process)d:打印进程ID
%(message)s:打印日志信息

# logging 简单例子
import logging


file_name='./Gnerate_files/logging_test.log'
logging.basicConfig(
    level=logging.INFO,
    filename=file_name,
    filemode='w+', # 这里针对本例子使用w,但是日志记录时不建议使用w
    format='%(lineno)s\t%(asctime)s: %(name)s: %(levelname)s: %(message)s')

logger = logging.getLogger(name=__name__)

logger.info("Start print log INFO")
logger.debug("Start print log DEBUG")
logger.warning("Start print log WARNING")
logger.info("the print log INFO is end")

print("日志文件内容:")
with open(file_name, 'r', encoding='utf-8', buffering=1024) as file:
    lines = file.readlines()
    for line in lines:
        print(line)

日志文件内容:
14	2020-02-07 13:18:03,459: __main__: INFO: Start print log INFO

16	2020-02-07 13:18:03,460: __main__: WARNING: Start print log WARNING

17	2020-02-07 13:18:03,460: __main__: INFO: the print log INFO is end
'''logger中添加StreamHandler,可以将日志输出到屏幕上'''
# 将日志同时输出到屏幕和日志文件例子
import logging

file_name = './Gnerate_files/logging_test_f_c.log'
loggerc = logging.getLogger(__name__)
loggerc.setLevel(level=logging.INFO)
handler = logging.FileHandler(file_name, mode='w+', encoding='utf-8')
handler.setLevel(logging.INFO)
formatter = logging.Formatter(
    '%(asctime)s: %(name)s %(levelname)s %(message)s')
handler.setFormatter(formatter)

console = logging.StreamHandler()
console.setLevel(logging.INFO)
loggerc.addHandler(handler)
loggerc.addHandler(console)

loggerc.info("Start print log INFO")
loggerc.debug("Start print log DEBUG")
loggerc.warning("Start print log WARNING")
loggerc.info("the print log INFO is end")

print("日志文件内容:")
with open(file_name, 'r', encoding='utf-8', buffering=1024) as file:
    lines = file.readlines()
    for line in lines:
        print(line)
Start print log INFO
Start print log WARNING
the print log INFO is end


日志文件内容:
2020-02-07 13:18:10,353: __main__ INFO Start print log INFO

2020-02-07 13:18:10,355: __main__ WARNING Start print log WARNING

2020-02-07 13:18:10,356: __main__ INFO the print log INFO is end
pdb调试

pdb 调试有个明显的缺陷就是对于多线程,远程调试等支持得不够好,

同时没有较为直观的界面显示,不太适合大型的 python 项目。

pdb操作指令

命令 简写 功能 注解
break b 设置断点
continue c 继续执行程序
list l 查看当前行的代码
step s 进入函数
return r 执行代码直到从当前函数返回
quit q 终止并退出
next n 执行下一行
print p 打印变量的值
help h 帮助
args a 查看传入参数
  回车 重复上一条命令
break b 显示所有断点
break lineno b lineno 在指定行设置断点
break file:lineno b file:lineno 在指定文件的行设置断点
clear num   删除指定断点 这里的num不是添加断点的行号,而是断点的序号
bt   查看函数调用栈帧

pdb交互调试

import pdb

pdb.run(funcName(attribute)) # 这里需要在pdb中先按s,然后才可以l,不然不会显示代码

pdb程序里埋点

import pdb

pdb.set_trace() # 当程序遇到这句话时才进入调试

发布了13 篇原创文章 · 获赞 0 · 访问量 25

猜你喜欢

转载自blog.csdn.net/qq_34764582/article/details/104940438
今日推荐