数据蛙数据分析基础学习

python——错误和异常

2020-02-02  本文已影响0人  Gaafung峰

导言

学习python过程中总会遇到各种错误,但没有一个体系化讲解,这篇文章是总结python的错误和异常。
按以下路径讲解:
1.错误和异常
2.捕获异常
3.主动抛异常
4.如何分析和收集异常

资料来源:错误和异常

错误和异常

1.错误

错误通常指语法错误,在程序解析阶段会被发现。
示例

a = “python”
print(a)
  File "<ipython-input-5-8c4ed26a3a35>", line 1
    a = “python”
               ^
SyntaxError: invalid character in identifier

该错误则是中文引号错误导致 语法错误(SyntaxError)。

2.异常

异常指的是程序没有语法错误,但运行期间仍然报错。
示例TypeError

def test(a, c):
    print(a+c)


if __name__ == '__main__':
    test(2, 3)
    test('2', 3)

显然,test('2',3)会产生格式错误,字符串+数值无法获得结果

2.1 异常在什么时候发生

异常只有遇到特定情况时才会发生错误,本身语句并没有 问题。

所以,在写程序过程中,程序员会考虑特殊情况,刻意处理边界情况或特殊情况,避免错误。

通常会使用try...except...else...finally处理,后文详细讲解。

3.异常类继承关系

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
       |     +-- FloatingPointError
       |     +-- OverflowError
       |     +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
           +-- ModuleNotFoundError
      +-- LookupError
       |     +-- IndexError
       |     +-- KeyError
      +-- MemoryError
      +-- NameError
       |     +-- UnboundLocalError
      +-- OSError
       |     +-- BlockingIOError
       |     +-- ChildProcessError
       |     +-- ConnectionError
       |      |     +-- BrokenPipeError
       |      |     +-- ConnectionAbortedError
       |      |     +-- ConnectionRefusedError
       |      |     +-- ConnectionResetError
       |     +-- FileExistsError
       |     +-- FileNotFoundError
       |     +-- InterruptedError
       |     +-- IsADirectoryError
       |     +-- NotADirectoryError
       |     +-- PermissionError
       |     +-- ProcessLookupError
       |     +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
       |     +-- NotImplementedError
       |     +-- RecursionError
      +-- SyntaxError
       |     +-- IndentationError
       |          +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
       |     +-- UnicodeError
       |          +-- UnicodeDecodeError
       |          +-- UnicodeEncodeError
       |          +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

如何捕获异常

通常程序发生异常,就会终止。
终止导致的结果:
1.后续程序应继续执行却被终止
2.无法保留异常信息

所以需要将异常捕获。

1.try

python中,捕获异常使用try ... except ...这种语法来捕捉异常,下面是一个异常捕获的示例

def test(a, b):
    try:
        print(a/b)
    except ZeroDivisionError:
        print("0不能作分母")

if __name__ == '__main__':
    test(10, 5)
    test(10, 0)

优化一下可以使用logging模块

2.except

except 可以指定想要捕获的异常,比如上面的例子中,代码想捕获ZeroDivisionError 异常,如果try子句中发生了别的异常,这个except 就不会捕捉。
针对不同的异常做不同的处理,你可以一次性指定想要捕获的所有异常,比如下面的代码

def test(a, b):
    try:
        print(a/b)
    except (ZeroDivisionError, ValueError):
        return None

if __name__ == '__main__':
    test(10, 5)
    test(10, 0)

也可以逐个捕捉

def test(a, b):
    try:
        print(a/b)
    except ZeroDivisionError:
        print('0不能做分母')
    except ValueError:
        print("类型错误")
    else:
        print('什么异常都没发生')

if __name__ == '__main__':
    test(10, 5)
    test(10, 0)

try ... except ... else这种语法,当没有异常发生时,就会执行else语句块里的代码。

万能用法:

def test(a, b):
    try:
        print(a/b)
    except:
        print('发生异常')

if __name__ == '__main__':
    test(10, 5)
    test(10, 0)

3.finally

finally是清理收尾的定位,也就是不管try..except发生什么,最终都会执行finally的代码

def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("division by zero!")
    else:
        print("result is", result)
    finally:
        print("executing finally clause")

if __name__ == '__main__':
    divide(10, 5)
    divide(10, 0)

主动抛异常

1.抛异常

抛异常的使用场景通常是
1.上层调用者希望能够捕获自定义异常
2.本身并不是异常,但根据业务场景属于异常或特殊情况

示例

def divide(x, y):
    if y == 0:
        raise ZeroDivisionError("0不能做分母")
    return x/y

if __name__ == '__main__':
    divide(10, 5)
    divide(10, 0)

抛出异常时,你可以指定抛出哪个异常,如果你不想指定,那么可以抛出异常Exception, 它是所有异常的父类

def divide(x, y):
    if y == 0:
        raise Exception("0不能做分母")
    return x/y

if __name__ == '__main__':
    divide(10, 5)
    divide(10, 0)

2.自定义异常

import requests


class HttpCodeException(Exception):
    pass

def get_html(url, headers):
    res = requests.get(url, headers=headers)
    print(res.status_code)
    if res.status_code != 200:
        raise HttpCodeException

    return res.text

try:
    text = get_html("http://www.coolpython.net", {})
    print(text)
except HttpCodeException:
    print("状态码不是200")

这样子能够更有针对性处理异常

异常信息分析与收集

1. 异常信息分析

def func_tet():
    func_sum('4', 3)


def func_sum(a, b):
    value = a + b
    return value


func_tet()

报错信息如下:


image.png

异常信息分为两部分,红色+蓝色。

分析时,先关注最后一行蓝色框内的信息,这里的信息明确的指明了异常的类型和异常的解释信息。

第二部分,就是红色框内的内容,是调用堆栈信息,详细的记录了程序的执行路径,最后一行正是错误发生的位置。

现在,既有出错代码的位置,又有错误的类型与解释,如果还是不能找出问题,那么,可以百度了,百度时将最后一行蓝色框里的内容作为搜索词进行搜索,可以找到大量文章。

上一篇下一篇

猜你喜欢

热点阅读