文章目录
笔记中代码均可运行在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
'''
调试
最简单
断言(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 | 执行下一行 | 无 |
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() # 当程序遇到这句话时才进入调试