python错误和异常

本文译自https://docs.python.org/2.7/tutorial/。完全是出于个人兴趣翻译的,请勿追究责任。另外,谢绝商业牟利。刊印请与本人和原作者联系,无授权不得刊印,违者必究其责任。如需转发,请注明来源,并保留此行,尊重本人的劳动成果,谢谢。

来源:CSDN博客

作者:奔跑的QQEE

(本文有删改)

python错误和异常

一、语法错误

初学python时,可能最经常遇到的就是这种错误了。例:

>>> while True print 'Hello world'
  File "<stdin>", line 1
    while True print 'Hello world'
                   ^
SyntaxError: invalid syntax
二、异常

不多解释。例:

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo 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: cannot concatenate 'str' and 'int' objects
三、异常处理

python中的异常处理是这样的。例:

>>>     try:
...         x = int(raw_input("Please enter a number: "))
...         break
...     except ValueError:
...         print "Oops!  That was no valid number.  Try again..."
...
  • 首先执行try代码块。
  • 如果没有发生异常,except代码块将被忽略。try代码块被完全执行。
  • 如果发生了异常,try块余下的代码将被跳过,随后会将异常类型与except关键字定义的异常种类匹配。匹配成功则执行对应的except块。
  • 若发生了未定义的异常,则会抛出unhandled exception提示。

一个try块可能有多个处理不同异常的except块。为了简洁,可以将多个异常类型写到一个except类型定义中。例:

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

注意:上面的括号是有必要的。except valueError,e:表示except valueError as e:

再看个例子:

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as e:
    print "I/O error({0}): {1}".format(e.errno, e.strerror)
except ValueError:
    print "Could not convert data to an integer."
except: #捕获其它异常
    print "Unexpected error:", sys.exc_info()[0]
    raise

try...except语块后面还可跟一可选语块,else语块。此语块在try块没有发生错误时才执行,必须位于except块后。它与python中的finally语块不同。finally块是无论异常发生否,都将执行此块。例:

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

当异常发生时,往往会有相关值返回。这值就是通常说的异常的参数。此值取决于异常的种类。

except块可能会在异常名或元组名后指定一变量。此变量指向异常实例,该异常实例的参数存储于instance.args内。为便于使用,此异常实例中内置了__str__()方法,这样就可以直接输出参数值,而不用引用.args。例:

>>> try:
...     raise Exception('spam', 'eggs') # 抛出异常前先为之传递属性
... except Exception as inst:
...     print type(inst)     # 异常实例类型
...     print inst.args      # 存于 .args 中的参数值
...     print inst           # 因为__str__(),所以会输出参数值 
...     x, y = inst.args
...     print 'x =', x
...     print 'y =', y
...

<type 'exceptions.Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs

再来看一个例子。不多解释。

>>> def this_fails():
...     x = 1/0
...
>>> try:
...     this_fails()    # 此块在调用 this_fails() 时发生异常
... except ZeroDivisionError as detail:
...     print 'Handling run-time error:', detail
...
Handling run-time error: integer division or modulo by zero
四、抛出异常

raise语句可使强制抛出指定异常。例:

>>> raise NameError('HiThere')

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

raise后的参数表明此种异常将被抛出。需要注意,该参数要么是一异常实例,要么是一异常类。

可重复抛出同种类型异常。例:

>>> try:
...     raise NameError('HiThere')  # 有异常发生,交给 except 块处理
... except NameError:
...     print 'An exception flew by!'
...     raise   # 抛出异常。默认是 NameError 类型的异常
...

An exception flew by!
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
NameError: HiThere
五、自定义异常

可通过创建异常类来自定义异常。自定义的类必须直接或间接地派生于Exception类。

例:

>>> class MyError(Exception):
...     def __init__(self, value): # 重写了__init__()
...         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 "<stdin>", line 1, in <module>
__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:
        expr -- input expression in which the error occurred
        msg  -- explanation of the error
    """

    def __init__(self, expr, msg):
        self.expr = expr
        self.msg = msg

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

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

    def __init__(self, prev, next, msg):
        self.prev = prev
        self.next = next
        self.msg = msg
六、finally

例:

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

无论是否发生异常,finally块都将被执行。若发生了没有被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"
...

>>> divide(2, 1)    # 未发生异常,执行 else,finally 块
result is 2
executing finally clause

>>> divide(2, 0)    # 发生了定义的异常,执行 except,finally 块
division by zero!
executing finally clause

>>> divide("2", "1")    #发生了未定义的异常,执行 finally块,然后抛出异常
executing finally clause
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'
七、with

例:

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

这将打开文件myfile.txt,并输出所有行。

然而这两行代码是有问题的:输出完毕后,文件仍然处于打开状态。处理的方法是用python提供的with关键字。例:

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

这样即使输出时发生了错误也能将文件安全关闭。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值