Python常见异常分类与处理
def bar(s):Python常见异常类型大概分为以下类:
python抛出异常继续执行 python3异常可直接抛出
except ValueError, e:
1.AssertionError:当assert断言条件为假的时候抛出的异常
2.AttributeError:当访问的对象属性不存在的时候抛出的异常
3.IndexError:超出对象索引的范围时抛出的异常
4.KeyError:在字典中查找一个不存在的key抛出的异常
5.NameError:访问一个不存在的变量时抛出的异常
6.OSError:作系统产生的异常
7.SyntaxError:语法错误时会抛出此异常
8.TypeError:类型错误,通常是不通类型之间的作会出现此异常
9.ZeroDivisionError:进行数算时除数为0时会出现此异常
关于更多异常请参考文档:
2.7版本链接
3.6版本链接
Python异常处理:
例1:出现异常最简单处理方法
?1
234
567801112
#coding:utf8
#try与except结合用法
a=
1b
=2
try
assert
ab
#如果ab判断为假时将抛出AssertionError异常
except
AssertionError:
#如果捕获到AssertionError异常将执行except下面的代码块
(ab)
上面例子输出结果为 ab为假,这时候会抛出AssertionError异常,当捕获到此异常后就会执行except代码块中的语句
例2:使用多个except捕获异常
?123456780111213141516
#coding:utf8
#try与多个except结合用法,在try代码块中依次执行,只要捕获到异常就停止执行
while True: try:try: 重复执行内容 except: 输出异常 else: retrying是一个 Python的重试包,可以用来自动重试一些可能运行失败的程序段。retrying提供一个装饰器函数retry,被装饰的函数就会在运行失败的条件下重新执行,默认只要一直报错就会不断重试。 import randomfrom retrying import retry @retrydef do_soming_unreliable(): if random.randint(0, 10) > 1: raise IOError("Broken sauce, rything is hosed!!!111one") else: return "Awesome sauce!" print do_soming_unreliable()
如果我们运行he_a_try函数,那么直到random.randint返回5,它才会执行结束,否则会一直重新执行。 retry还可以接受一些参数,这个从源码中Retrying类的初始化函数可以看到可选的参数:
stop_max_attempt_number:用来设定的尝试次数,超过该次数就停止重试 stop_max_delay:比如设置成10000,那么从被装饰的函数开始执行的时间点开始,到函数成功运行结束或者失败报错中止的时间点,只要这段时间超过10秒,函数就不会再执行了 wait_fixed:设置在两次retrying之间的停留时间 wait_random_min和wait_random_max:用随机的方式产生两次retrying之间的停留时间 wait_exponential_multiplier和wait_exponential_max:以指数的形式产生两次retrying之间的停留时间,产生的值为2^previous_attempt_number wait_exponential_multiplier,previous_attempt_number是前面已经retry的次数,如果产生的这个值超过了wait_exponential_max的大小,那么之后两个retrying之间的停留值都为wait_exponential_max。这个设计迎合了exponential backoff算法,可以减轻阻塞的情况。 我们可以指定要在出现哪些异常的时候再去retry,这个要用retry_on_exception传入一个函数对象: def retry_if_io_error(exception): return isinstance(exception, IOError) @retry(retry_on_exception=retry_if_io_error)def read_a_file(): with open("file", "r") as f: return f.read() 在执行read_a_file函数的过程中,如果报出异常,那么这个异常会以形参exception传入retry_if_io_error函数中,如果exception是IOError那么就进行rprint 'END'etry,如果不是就停止运行并抛出异常。 我们还可以指定要在得到哪些结果的时候去retry,这个要用retry_on_result传入一个函数对象: def retry_if_result_none(result): return result is None @retry(retry_on_result=retry_if_result_none)def get_result(): return None 在执行get_result成功后,会将函数的返回值通过形参result的形式传入retry_if_result_none函数中,如果返回值是None那么就进行retry,否则就结束并返回函数值。 抛出异常是停止运行这个函数中END....>>>由于没有错误发生,所以except语句块不会被执行,但是finally如果有则一定会被执行,当然finally也可以没有的代码。 哈希算法将一个不定长的输入,通过散列函数变换成一个定长的输出,即散列值。是一种信息摘要算法。对象的hash值比原对象拥有更低的Traceback (most recent call last):内存复杂度。 它不同于加密。哈希是将目标文本转换成具有相同长度的,不可逆的杂凑字符串,而加密则是将文本转换为具有相同长度的,可逆的密文。哈希算法是不可逆的,只能由输入产生输出,不能由输出产生输入。而加密则是可逆的。即可以从输入产生输出,也可以反过来从输出推出输入。 看下面的两个例子,它们的作用是完全一样的,非常简单,给除数和被除数,计算除法的结果。 这可能是世界上最没用的函数之一,但重点不在这里。重点在于下面的问题: 继续看之前,先考虑一下。给出自己的。 Python们一般会 「种」 使用异常的写法。理由如下: 异常处理的代码是只有发生了异常才会去执行。既然绝大部分情况下不会发生异常,那就没必每次都做事前判断,这样会很浪费CPU的运算力。假设100次调用,只有1次有问题,却要做100次if判断,不浪费吗? 反过来使用异常的方法,只有 出现 了异常才去做处理,那么except语句只会执行一次。 通过这个对比,我们也可以看到: 试想一下,如果我们可以取消做飞机时候的各种事前检查,是不是可以大大提高效率呢? 现实生活中,我们不能取消这种检查。但在程序中,我们可以,因为我们可以用异常捕捉。 现在给大家两条Python异常处理的哲学: 在Python中,try语句用于异常处理。它提供了一种结构化的方式来捕获并处理可能发生的异常。 Try:紧跟其后的缩进代码块是可能会抛出异常的代码。 Except 异常类型1:用于处理特定类型的异常。如果在try代码块中发生该类型的异常,程序将跳转到对应的except块执行相应的处理逻辑。 Exc也就是说,不需要在每个可能出错的地方去捕获异常,只要在合适的层次去捕获就可以了。ept 异常类型2 as 变量:用于处理特定类型的异常,并将异常信息存储在指定的变量中。 Except (异常类型3, 异常类型4):用于处理多个异常类型,可以将它们放在括号内,并在同一个except块中处理。 Except:用于处理所有其他类型的异常。如果在try代码块中发生未被上述except块捕获的异常,程序将跳转到此处执行处理逻辑。 Finally:无论是否发生异常,finally代码块中的代码都会被执行。通常用于释放资源或进行清理作。 Python语句注意事项 1、缩进:Python使用缩进来表示代码块的结构,因此正确的缩进对于代码的正确性至关重要。请确保代码块内的所有行都具有相同的缩进级别,并使用空格或制表符进行缩进。 2、冒号:在Python中,冒号用于引入代码块Traceback (most recent call last):(如条件语句、循环语句、函数定义等)。请确保在需要冒号的地方使用它,并在冒号后面换行并缩进。 3、变量命名规范:选择有意义的变量名称可以增加代码的可读性。遵循Python的命名规范,使用小写字母、下划线分隔单词的方式来命名变量和函数。避免使用Python的保留字作为变量名。 random.uniform 用于生成一个指定范围内的随机符点数,两个参数其中一个是上限,一个是下限。pass如果a > b,则生成的随机数n: a <= n <= b。如果 a 在程序运行的过程中,如果发生了错误,可以事先约定返回一个错误代码,这样,就可以知道是否有错,以及出错的原因。在作系统提供的调用中,返回错误码非常常见。比如打开文件的函数open(),成功时返回文件描述符(就是一个整数),出错时返回-1。 用错误码来表示是否出错十分不便,因为函数本身应该返回的正常结果和错误码混在一起,造成调用者必须用大量的代码来判断是否出错: def foo(): r = some_function() if r==(-1): return (-1) # do soming return r def bar(): r = foo() if r==(-1): print 'Error' else: 一旦出错,还要一级一级上报,直到某个函数可以处理该错误(比如,给用户输出一个错误信息)。 所以高级语言通常都内置了一套try...except...finally...的错误处理机制,Python也不例外。 try 让我们用一个例子来看看try的机制: print 'try...' r = 10 / 0 print 'result:', r except ZeroDivisionError, e: print 'except:', e print 'finally...' 当我们认为某些代码可能会出错时,就可以用try来运行这段代码,如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即except语句块,执行完except后,如果有finally语句块,则执行finally语句块,至此,执行完毕。 上面的代码在计算10 / 0时会产生一个除法运算错误: try... except: integer division or modulo by zero finally... 从输出可以看到,当错误发生时,后续语句print 'result:', r不会被执行,except由于捕获到ZeroDivisionError,因此被执行。,finally语句被执行。然后,程序继续按照流程往下走。 如果把除数0改成2,则执行结果如下: try... result: 5 finally... 由于没有错误发生,所以except语句块不会被执行,但是finally如果有,则一定会被执行(可以没有finally语句)。 你还可以猜测,错误应该有很多种类,如果发生了不同类型的错误,应该由不同的except语句块处理。没错,可以有多个except来捕获不同类型的错误: print 'try...' r = 10 / int('a') print 'result:', r except ZeroDivisionError, e: print 'ZeroDivisionError:', e print 'finally...' int()函数可能会抛出ValueError,所以我们用一个except捕获ValueError,用另一个except捕获ZeroDivisionError。 此外,如果没有错误发生,可以在except语句块后面加一个else,当没有错误发生时,会自动执行else语句: print 'try...' r = 10 / int('a') print 'result:', r except ZeroDivisionError, e: print 'ZeroDivisionError:', e else: print 'no error!' print 'finally...' Python的错误其实也是class,所有的错误类型都继承自BaseException,所以在使用except时需要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽”。比如: foo() except StandardError, e: print 'StandardError' print 'ValueError' 第二个except永远也捕获不到ValueError,因为ValueError是StandardError的子类,如果有,也被个except给捕获了。 Python所有的错误都是从BaseException类派生的 使用try...except捕获错误还有一个巨大的好处,就是可以跨越多层调用,比如函数main()调用foo(),foo()调用bar(),结果bar()出错了,这时,只要main()捕获到了,就可以处理: def foo(s): return 10 / int(s) return foo(s) 2 bar('0') except StandardError, e: print 'Error!' print 'finally...' 也就是说,不需要在每个可能出错的地方去捕获错误,只要在合适的层次去捕获错误就可以了。这样一来,就大大减少了写try...except...finally的麻烦。 调用堆栈 如果错误没有被捕获,它就会一直往上抛,被Python解释器捕获,打印一个错误信息,然后程序退出。来看看err.py: # err.py: def foo(s): return 10 / int(s) return foo(s) 2 bar('0') main() 执行,结果如下: $ python err.py main() File "err.py", line 9, in main bar('0') File "err.py", line 6, in bar return foo(s) 2 File "err.py", line 3, in foo return 10 / int(s) ZeroDivisionError: integer division or modulo by zero 出错并不可怕,可怕的是不知道哪里出错了。解读错误信息是定位错误的关键。我们从上往下可以看到整个错误的调用函数链: 错误信息第1行: 告诉我们这是错误的跟踪信息。 第2行: main() 调用main()出错了,在代码文件err.py的第11行代码,但原因是第9行: File "err.py", line 9, in main bar('0') 调用bar('0')出错了,在代码文件err.py的第9行代码,但原因是第6行: File "err.py", line 6, in bar return foo(s) 2 原因是return foo(s) 2这个语句出错了,但这还不是最终原因,继续往下看: File "err.py", line 3, in foo return 10 / int(s) 原因是return 10 / int(s)这个语句出错了,这是错误产生的源头,因为下面打印了: ZeroDivisionError: integer division or modulo by zero 根据错误类型ZeroDivisionError,我们判断,int(s)本身并没有出错,但是int(s)返回0,在计算10 / 0时出错,至此,找到错误源头。 记录错误 如果不捕获错误,自然可以让Python解释器来打印出错误堆栈,但程序也被结束了。既然我们能捕获错误,就可以把错误堆栈打印出来,然后分析错误原因,同时,让程序继续执行下去。 Python内置的logging模块可以非常容易地记录错误信息: # err.py import logging def foo(s): return 10 / int(s) return foo(s) 2 bar('0') except StandardError, e: main() 同样是出错,但程序打印完错误信息后会继续执行,并正常退出: $ python err.py ERROR:root:integer division or modulo by zero File "err.py", line 12, in main bar('0') return foo(s) 2 File "err.py", line 5, in foo return 10 / int(s) ZeroDivisionError: integer division or modulo by zero 通过配置,logging还可以把错误记录到日志文件里,方便事后排查。 抛出错误 因为错误是class,捕获一个错误就是捕获到该class的一个实例。因此,错误并不是凭空产生的,而是有意创建并抛出的。Python的内置函数会抛出很多类型的错误,我们自己编写的函数也可以抛出错误。 如果要抛出错误,首先根据需要,可以定义一个错误的class,选择好继承关系,然后,用raise语句抛出一个错误的实例: # err.py class FooError(StandardError): def foo(s): n = int(s) if n==0: raise FooError('invalid value: %s' % s) return 10 / n 执行,可以跟踪到我们自己定义的错误: $ python err.py ... __main__.FooError: invalid value: 0 只有在必要的时候才定义我们自己的错误类型。如果可以选择Python已有的内置的错误类型(比如ValueError,TypeError),尽量使用Python内置的错误类型。 ,我们来看另一种错误处理的方式: # err.py def foo(s): n = int(s) return 10 / n return foo(s) 2 except StandardError, e: print 'Error!' raise bar('0') main() 在bar()函数中,我们明明已经捕获了错误,但是,打印一个Error!后,又把错误通过raise语句抛出去了,这不有病么? 其实这种错误处理方式不但没病,而且相当常见。捕获错误目的只是记录一下,便于后续。但是,由于当前函数不知道应该怎么处理该错误,所以,最恰当的方式是继续往上抛,让顶层调用者去处理。 raise语句如果不带参数,就会把当前错误原样抛出。此外,在except中raise一个Error,还可以把一种类型的错误转化成另一种类型: except ZeroDivisionError: raise ValueError('input error!') 只要是合理的转换逻辑就可以,但是,决不应该把一个IOError转换成毫不相干的ValueError。 小结 Python内置的try...except...finally用来处理错误十分方便。出错时,会分析错误信息并定位错误发生的代码位置才是最关键的。 程序也可以主动抛出错误,让调用者来处理相应的错误。但是,应该在文档中写清楚可能会抛出哪些错误,以及错误产生的原因。 抛出异常就应该能用了,如果出现未知列或者其他不对的列都会直接排除异常然后继续执行 try: 语句 except: 把0导入float列 版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 12345678@qq.com 举报,一经查实,本站将立刻删除。python 如果一段代码报错,想让他回到问题开头重复执行。代码如下:#获取数据
print 'ValueError:', ePython中异常重试怎么解决
File "err.py", line 11, in Python哈希函数什么情况下抛出异常
聊聊Python异常处理的哲学,懂了以后豁然开朗
ValueErroFile"C:/Python36/test.py", line8, in mainr: do not input zero!>>>只要是合理的转换逻辑就可以,但是,绝不应该把一个IOError转成毫不相干的valueError.python try用法
python异常和错误的区别
logging.exception(e)我执行一段python脚本报错了,怎么解决
finally:我在用python数据到mysql的时候,有些列是float类型,但是导出的数据中有些是nan这种,在执行的时候报错
File "err.py", line 8, in bar