python调试⼤法-⼤笨蛋的笔记说在前⾯
我觉得没有什么错误是调试器⽆法解决的,如果没有,那我再说⼀遍,如果有,那当我没说
⼀、抛出异常
可以通过 raise 语句抛出异常,使程序在我们已经知道的缺陷处停下,并进⼊到 except 语句
raise句法:
raise关键字
调⽤的异常函数名 ValueError (这个函数必须是异常类或⼀个实例)
传递给 ValueError 的字符串,包含有⽤的出错信息
>>> raise ValueError('This is a error message')
Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
raise ValueError('This is a error message')
ValueError: This is a error message
然后使⽤ pt 语句来对抛出的异常做处理
通常我们在函数本⾝中抛出异常,然后在调⽤该函数的地⽅使⽤ pt 语句处理异常
#定义⼀个简单的int类型的加法器
def calculator(num1,num2):
if isintance(num1,int)and isintance(num2,int):
raise Exception('Symbol must be a int type number.')
return num1+num2
print('please enter two number:')
num1=input()
num2=input()
#在调⽤函数的地⽅使⽤try语句
try:
print(calculator(num1,num2))
except Exception as err:
print('发⽣了⼀个错误:'+str(err))
注意上⾯的 as 语句取得 str ,如果不取也是可以的
运⾏⽰例:
RESTART: C:/Users/Administrator.SC-201605202132/AppData/Local/Programs/Python/Python37/boxPrint.py please enter two number:
1
s
发⽣了⼀个错误:name 'isintance'is not defined
>>>
⼆、取的反向跟踪的字符串
当程序运⾏出现错误时,python会⽣成⼀些错误信息,这些错误信息被称为“反向跟踪”,它包含了出错信息、导致该错误的代码⾏号,和导致 该错误的函数调⽤ 的 序列,这个序列被称为调⽤栈。
只要抛出的异常没有被处理,python就会显⽰反向跟踪
以下⾯程序来展⽰我们对反向跟踪的解读
def spam():
bacon()
def bacon():
raise Exception('This is the error message')
spam()
这就是反向跟踪:
Traceback (most recent call last):
File "C:/Users/Administrator.SC-201605202132/AppData/Local/Programs/Python/Python37/errorExample.py", line 6, in <module>
spam()
File "C:/Users/Administrator.SC-201605202132/AppData/Local/Programs/Python/Python37/errorExample.py", line 2, in spam
bacon()
File "C:/Users/Administrator.SC-201605202132/AppData/Local/Programs/Python/Python37/errorExample.py", line 4, in bacon
raise Exception('This is the error message')
Exception: This is the error message
我们应该从下往上阅读⽅向跟踪,通过反向跟踪我们可以知道,这个错误发⽣在第5⾏,在bacon函数中;这次特定的bacon调⽤发⽣在第2⾏,spam函数中,⽽spam函数⼜是在第6⾏被调⽤的。这样,在从多个位置调⽤函数的程序中,调⽤栈就能帮助你确定那次调⽤导致了错误。
调⽤ traceback.format_exc() 得到反向跟踪的字符串形式
前⾯说过,如果抛出的异常没有被处理,python才会显⽰反向跟踪。假如我们既想⽤except处理错误,⼜想要获得出错信息,就可以⽤这个函数,需要导⼊ traceback 模块
python新手能做啥兼职 例如,我们可以在程序出现错误时还能继续运⾏,同时把错误信息记录到⽇志中。在程序结束后调试程序时,我们就根据⽇志⾥记录的信息去调试
>>> import traceback
>>> try:
raise Exception('This is a error message')
except:
errorFile=open('','w')
errorFile.write(traceback.format_exc()) #使⽤tracback.format_exc()获得反向跟踪的字符串形式
errorFile.close()
print('The traceback info was written ')
112 #返回的是写⼊的字符个数
The traceback info was written
>>>
的内容:
Traceback (most recent call last):
File "<pyshell#8>", line 2, in <module>
Exception: This is a error message
三、断⾔assert语句
举⼀个例⼦。你从学校毕业以后,很久都没有到⼯作,有⼀天你了⼀个兼职:宝⽯⼤管家。⼩孩需要拿着与他们⾝份匹配的标识才能在别处领到宝⽯,这个标识在你这⾥领取,你⼯作做得不错,才做了五分钟就被⽼板任命为了区域经理,你觉你年纪轻轻就已经成为了⼆龙⼭云霄飞车街区的揸Fit⼈、并且⼀⼿建⽴了⼆龙⼭游乐场宝⽯交易的游戏法则,觉得⼈⽣巅峰也不过如此,但是,沉迷于⾃我陶醉的你根本不知道,你将⼀个错误的标识给了⼀个⼩朋友,导致他没有领到宝⽯。结果他叫他哥哥来打你了⼀顿。然后你⽼板觉得你辜负了他对你的栽培,然后⼀⽓之下把你开了,⼯资当然没有结。最惨的是,你的⾐服丢了,当时你为了⽤肚脐眼上的伤疤吓唬他就把⾐服脱了,结果他竟然也有同样的伤疤,然后⼜被他打了⼀顿,然后,你的⾐服就丢了。你知道这是你最宝贵的财富,因为这是当年⼥神赠你的礼物,你永远也忘不了毕业那天,在你的寝室楼下,他轻轻的把袋⼦递给了你,那天你们说了很多,他说感谢你四年来对他的照顾,但是他妈妈不让他谈恋爱,所以让你再等等,你和他⼀直聊到晚上10点,只为了能当⾯向他说⼀句晚安,他很欣赏你的执着,离别之际对你许下了⼀个承诺:她说假如有⼀天这件⾐服变成了绿⾊,他⼀定和你结婚。你知道,这下肯定没有希望了。不仅失去了⼯作,你失去了爱情。你以为丢了⾐服,就再也没机会和他结婚了,万万没想到,最后你们还是成为了夫妻。那天你回来以后就去了⽹吧,看见旁边的⼈在写代码,他周围散落的零⾷包装代表着富有,这⼀切都被你看在眼⾥,你知道你看到了希望,然后你就开始学编程了,由于你过⼈的天赋,没出⼏⼗年你就⾃⼰创办了⼀家公司,和阿⾥啪啪,中国移不动等⼤公司都建⽴了不同程度的合作关系,且业务往来⼗分密切,⾝边的⼈都夸你有出息,只是在深夜的时候,你常常想起当年的那个他,
你祈求⽼天再给你⼀次机会,终于有⼀天,你qq收到了他的信息,她说要来你,你在城市最有档次的地⽅约她吃饭,他⼀眼就认出来了你,你很开⼼,你觉得他⼀点都没变,还是原来的样⼦,他没有问你⾐服的事情,只是不停的向你道歉说是⼿误当时才把你删了,其实他这些年⼀直在你,这次到你了,就是要和你结婚,你⼗分激动,但是你强忍着激动的⼼情,劝他在考虑考虑,他摇了摇头,从他眼神⾥流露出来的坚定瞬间击垮了你,你再也控制不了⾃⼰了,你拿出了那次做兼职留下的宝⽯钻戒,你⼀直把它带在⾝上,就是等着机会到来,他想都没想就⼀⼝答应了你的求婚。看到他对你如此信赖,你暗暗发誓⼀定要⽤全部的智商去爱她,晚上他⾮要枕着你的胳膊睡觉,你虽然觉的不舒服但还是让他枕了⼀夜,你做了⼀个梦,梦见你们有了⾃⼰的孩⼦,那件⾐服也被你到了 ⾐服上还写着“前⽅⾼能”⼏个字,这是你睡得最舒服的⼀个晚上,你早早就醒来了,发现他也已经起来了,就在床边上坐着,但令你不解的是,看到你睁开了眼睛,他的表情忽然很激动,sua的⼀声就哭了,等他冷静下来你才知道。原来,你应经昏迷了8年了,8年前,你去买早餐就再也没有回来,你出了车祸,昏迷了8年,留下他和他腹中的孩⼦。他说这些年他从来没有想过放弃你,他对你的爱帮助他克服了许多困难。如今你醒了,他终于成功了,他⾼兴的留下了激动的泪⽔,你也很开⼼。于是从此以后,你们⼀家三⼝过上了幸福的⽣活。
“断⾔”在这个⼯作流程当中,就是⽤来检查 你是否把牌发对了 的⼀个机制。为了避免这样的情况,我们就添加“断⾔”来检查。
assert语句包含:
assert关键字、要判断的条件、逗号、条件为False时显⽰的字符串
>>> podBayDoorStatus='open' #吊舱门的状态
>>> assert podBayDoorStatus=='open','podBayDoorStatus需要设置为open'
#这⾥结果没有错
>>> podBayDoorStatus='other content'
>>> assert podBayDoorStatus=='open','podBayDoorStatus需要设置为open'
#这⾥结果出错了
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
assert podBayDoorStatus=='open','podBayDoorStatus需要设置为open'
AssertionError: podBayDoorStatus需要设置为open
>>>
我们在程序中为某个变量赋值后,基于 这个变量是这个值 的假定,我们可能写下了⼤量的代码,即这些代码依赖这个值,才能正确⼯作。说以我们添加⼀个断⾔,确保假定的变量值是对的。
对于这种情况,我们使⽤assert让程序⽴即崩溃就,以减少寻缺陷的时间,我们不应⽤ try except 抛出异常,因为这是程序员的错误,⽽不是⽤户的错误,对于那些可以恢复的错误(如⽂件没有到,⽤户输⼊了⽆效的数据)则应该⽤抛出异常来处理
在交通灯模拟中使⽤断⾔
你在编写⼀个交通信号灯的模拟程序。代表路⼝信号灯的数据结构是⼀个字典:
market_2nd={'ns':'green','ew':'red'}#ns南北向,ew东西向
你希望编写⼀个函数 switchLight() ,他接受⼀个路⼝字典作为参数,并切换红路灯
你可能认为 switchLight() 只要将每⼀种灯按顺序切换到下⼀种颜⾊: ‘green‘ 值应该切换到 'yellow' , 'yellow' 应该切换
到 'red' , 'red' 应该切换到 'green' 实现这个功能的代码:
def switchLights(stoplight):
for key in stoplight.keys():
if stoplight[key]=='green':
stoplight[key]='yellow'
elif stoplight[key]=='yellow':
stoplight[key]='red'
elif stoplight[key]=='red':
stoplight[key]='green'
这样的运⾏结果:
>>>
RESTART: C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\forTest.py
{'ns': 'yellow', 'ew': 'green'}
{'ns': 'red', 'ew': 'yellow'}
{'ns': 'green', 'ew': 'red'}
你应该发现第⼀次的输出是错误的,因为南北向和东西向总应该有⼀个是红⾊的,如果不是,那么就会出现汽车相撞,为了避免这样的缺陷出现,你应该添加断⾔
market_2nd={'ns':'green','ew':'red'}#ns南北向,ew东西向
def switchLights(stoplight):
for key in stoplight.keys():
if stoplight[key]=='green':
stoplight[key]='yellow'
elif stoplight[key]=='yellow':
stoplight[key]='red'
elif stoplight[key]=='red':
stoplight[key]='green'
assert 'red' in stoplight.values(),'交通灯都不是红⾊的'+str(stoplight) #在函数⾥⾯添加断⾔
switchLights(market_2nd)
print(market_2nd)
switchLights(market_2nd)
print(market_2nd)
switchLights(market_2nd)
print(market_2nd)
假如你没有看出来这个代码有问题,然后也没有使⽤断⾔,当你从运⾏结果发现问题时,或许要好多时间才能发现问题出现
在 stwitchLight 函数中
禁⽤断⾔
当我们开发测试的时候,我们可以使⽤断⾔来帮助我们更早的发现错误,但是程序交付的时候应该是没有缺陷的,这时就不在需要断⾔了,我们可以在运⾏python时传⼊-O选项来禁⽤断⾔
需要从终端窗⼝运⾏程序时使⽤ >>><<<
四、⽇志
记⽇志是⼀种很好的⽅式,让我们可以理解程序中发⽣的事,以及事情发⽣的顺序。python中的 logging 模块让你能很容易的创建⾃定义的消息记录。这些⽇志消息列出了你指定的 任何变量 当时的值。缺失⽇志消息表明有⼀部分代码被跳过了,从未执⾏
4.1使⽤⽇志模块
import logging
logging.basicConfig(level=logging.DEBUG,format=' %(asctime)s - %(levelname)s - %(message)s')
我们使⽤ logging.debug('string') 来打印⽇志信息,这个 debug() 函数会调⽤ basicConfig ,所以我们第⼆⾏是指定打印信息的格式
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论