• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于python:Python基础之Python中的异常和错误

python 搞代码 3年前 (2022-02-20) 10次浏览 已收录 0个评论

简介

和其余的语言一样,Python中也有异样和谬误。在 Python 中,所有异样都是 BaseException 的类的实例。 明天咱们来具体看一下Python中的异样和对他们的解决形式。

Python中的内置异样类

Python中所有异样类都来自BaseException,它是所有内置异样的基类。

尽管它是所有异样类的基类,然而对于用户自定义的类来说,并不举荐间接继承BaseException,而是继承Exception.

先看下Python中异样类的构造关系:

<code class="shell">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

其中BaseExceptionExceptionArithmeticErrorBufferErrorLookupError 次要被作为其余异样的基类。

语法错误

在Python中,对于异样和谬误通常能够分为两类,第一类是语法错误,又称解析谬误。也就是代码还没有开始运行,就产生的谬误。

其产生的起因就是编写的代码不合乎Python的语言标准:

>>> while True print('Hello world')
  File "<stdin>", line 1
    while True print('Hello world')
                   ^
SyntaxError: invalid syntax

下面代码起因是 print 后面少了 冒号。

异样

即便咱们的程序合乎python的语法标准,然而在执行的时候,依然可能发送谬误,这种在运行时发送的谬误,叫做异样。

看一下上面的异样:

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly

异样解决

程序产生了异样之后该怎么解决呢?

咱们能够应用try except 语句来捕捉特定的异样。

>>> while True:
...     try:
...         x = int(input("Please enter a number: "))
...         break
...     except ValueError:
...         print("Oops!  That was no valid number.  Try again...")
...

下面代码的执行流程是,首先执行try中的子语句,如果没有异样产生,那么就会跳过except,并实现try语句的执行。

如果try中的子语句中产生了异样,那么将会跳过try子句中的前面局部,进行except的异样匹配。如果匹配胜利的话,就会去执行except中的子语句。

如果产生的异样和 except 子句中指定的异样不匹配,则将其传递到内部的 try语句中。

一个try中能够有多个except 子句,咱们能够这样写:

    try:
        raise cls()
    except D:
        print("D")
    except C:
        print("C")
    except B:
        print("B")

一个except也能够带多个异样:

... except (RuntimeError, TypeError, NameError):
...     pass

except 子句还能够省略异样名,用来匹配所有的异样:

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

tryexcept语句有一个可选的 else 子句,在应用时必须放在所有的 except 子句前面。对于在 try 子句不引发异样时必须执行的代码来说很有用。 例如:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except OSError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

except能够指定异样变量的名字 instance ,这个变量代表这个异样实例。

咱们能够通过instance.args来输入异样的参数。

同时,因为异样实例定义了 __str__(),所以能够间接应用print来输入异样的参数。而不须要应用 .args

咱们看一个例子:

>>> try:
...     raise Exception('spam', 'eggs')
... except Exception as inst:
...     print(type(inst))    # the exception instance
...     print(inst.args)     # arguments stored in .args
...     print(inst)          # __str__ allows args to be printed directly,
...                          # but may be overridden in exception subclasses
...     x, y = inst.args     # unpack args
...     print('x =', x)
...     print('y =', y)
...
<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs

下面的例子中,咱们在try字句中抛出了一个异样,并且指定了2个参数。

抛出异样

咱们能够应用raise语句来抛出异样。

>>> raise NameError('HiThere')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: HiThere

raise的参数是一个异样,这个异样能够是异样实例或者是一个异样类。

留神,这个异样类必须是Exception的子类。

如果传递的是一个异样类,那么将会调用无参构造函数来隐式实例化:

raise ValueError  # shorthand for 'raise ValueError()'

如果咱们捕捉了某些异样,然而又不想去解决,那么能够在except语句中应用raise,从新抛出异样。

>>> try:
...     raise NameError('HiThere')
... except NameError:
...     print('An exception flew by!')
...     raise
...
An exception flew by!
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
NameError: HiThere

异样链

如果咱们通过except捕捉一个异样A之后,能够通过raise语句再次抛出一个不同的异样类型B。

那么咱们看到的这个异样信息就是B的信息。然而咱们并不知道这个异样B是从哪里来的,这时候,咱们就能够用到异样链。

异样链就是抛出异样的时候,应用raise from语句:

>>> def func():
...     raise IOError
...
>>> try:
...     func()
... except IOError as exc:
...     raise RuntimeError('Failed to open database') from exc
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 2, in func
OSError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Failed to open database

下面的例子中,咱们在捕捉IOError之后,又抛出了RuntimeError,通过应用异样链,咱们很清晰的看出这两个异样之间的关系。

默认状况下,如果异样是从except 或者 finally 中抛出的话,会主动带上异样链信息。

如果你不想带上异样链,那么能够 from None

try:
    open('database.sqlite')
except IOError:
    raise RuntimeError from None

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError

自定义异样

用户能够继承 Exception 来实现自定义的异样,咱们看一些自定义异样的例子:

class Error(Exception):
    """Base class for exceptions in this module."""
    pass

class InputError(Error):
    """Exception raised for errors in the input.

    Attributes:
        expression -- input expression in which the error occurred
        message -- explanation of the error
    """

    def __init__(self, expression, message):
        self.expression = expression
        self.message = message

class TransitionError(Error):
    """Raised when an operation attempts a state transition that's not
    allowed.

    Attributes:
        previous -- state at beginning of transition
        next -- attempted new state
        message -- explanation of why the specific transition is not allowed
    """

    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message

finally

try语句能够跟着一个finally语句来实现一些收尾操作。

>>> try:
...     raise KeyboardInterrupt
... finally:
...     print('Goodbye, world!')
...
Goodbye, world!
KeyboardInterrupt
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>

finally 子句将作为 try 语句完结前的最初一项工作被执行, 无论try中是否产生异样,finally语句中的代码都会被执行。

如果 finally 子句中蕴含一个 return 语句,则返回值将来自 finally 子句的某个 return 语句的返回值,而非来自 try 子句的 return 语句的返回值。

>>> def bool_return():
...     try:
...         return True
...     finally:
...         return False
...
>>> bool_return()
False

本文已收录于 http://www.flydean.com/09-python-error-exception/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢迎关注搞代码gaodaima网的公众号:「程序那些事」,懂技术,更懂你!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于python:Python基础之Python中的异常和错误

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址