Python 学习笔记 - 第六天

1.语法错误

语法错误, 也称为解析错误:

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

2.异常

语法正常, 运行时检测到错误, 则为异常.

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

3.异常处理

通过编程来处理异常.
示例: 它会一直要求用户输入, 直到输入一个合法的整数为止, 但允许用户中断这个程序.
用户中断程序会引发一个KeyboardInterrupt异常.

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

一个try可以包含多个except, 一个except可以列出多个异常的名字:

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

最后一个except通常省略异常名, 作为通配. 可以重新抛出异常raise.

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

try...except可以在所有except后面带上一个else, 当try语句没有抛出异常时, 将执行else中的代码:

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

在异常名之后, 可以指定一个变量, 这个变量可以获取到一些异常信息:

>>> 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

异常处理器也捕获函数内部发生的异常:

>>> def this_fails():
...     x = 1/0
...
>>> try:
...     this_fails()
... except ZeroDivisionError as err:
...     print('Handling run-time error:', err)
...
Handling run-time error: int division or modulo by zero

4.抛出异常

raise允许强制抛出一个异常:

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

抛出的异常必须是一个异常实例或者异常类, 继承自Exception.

捕获异常后重新抛出:

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

5.自定义异常

异常类通常直接或间接从Exception类派生:

>>> class MyError(Exception):
...     def __init__(self, value):
...         self.value = value
...     def __str__(self):
...         return repr(self.value)
...
>>> try:
...     raise MyError(2*2)
... except MyError as e:
...     print('My exception occurred, value:', e.value)
...
My exception occurred, value: 4
>>> raise MyError('oops!')
Traceback (most recent call last):
  File "", line 1in ?
__main__.MyError: 'oops!'

定义异常基类, 再派生多种不同的异常类型:

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

大多数异常的命名都以Error结尾.

6.定期清理行为

无论异常是否捕获, finally都将在try执行完毕后执行.
示例:

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

即使在try中执行了break/continue/return退出了try, 同样也会执行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")
...
>>> divide(21)
result is 2
executing finally clause
>>> divide(20)
division by zero!
executing finally clause
>>> divide("2""1")
executing finally clause
Traceback (most recent call last):
  File "", line 1in ?
  File "", line 3in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'

7.预定义清理行为

with语句使得文件之类的对象可以确保及时准确地进行清理:

with open("myfile.txt"as f:
    for line in f:
        print(line)


你可能感兴趣的:(Python 学习笔记 - 第六天)