python2.7中文报错_python 2.7 中文教程8 - 错误和异常

至少有两种错误:语法错误和异常。

语法错误

语法错误又叫解析错误:

>>> while True print 'Hello world'

File "", line 1, in ?

while True print 'Hello world'

^

SyntaxError: invalid syntax

分析器指出错误行,并显示"

"在出错的地方。脚本执行时还会显示文件名和对应的行号,这里错误是print前面没有分号。

异常

即便语句或表达式语法正确,执行时也可能报错。运行时错误称为异常,它不会无条件的崩溃,通常是程序没有处理好:

>>> 10 * (1/0)

Traceback (most recent call last):

File "", line 1, in ?

ZeroDivisionError: integer division or modulo by zero

>>> 4 + spam*3

Traceback (most recent call last):

File "", line 1, in ?

NameError: name 'spam' is not defined

>>> '2' + 2

Traceback (most recent call last):

File "", line 1, in ?

TypeError: cannot concatenate 'str' and 'int' objects

ZeroDivisionError? , NameError和TypeError是异常类型,即异常的内置名,内置异常约定如此,建议自定义的异常也如此。标准异常名是内置的标识(但不是保留关键字)。异常名所在行的后续部分是异常类型的详细说明和产生原因。余下部分显示上下文,通常是堆栈traceback形式。通常列出了源代码行,但不会显示标准输入。

异常处理

下例一直要求用户输入,直到输入合法的整数,但允许用户中断(使用Control-C等)。 注意用户中断会产生KeyboardInterrupt异常。

>>> while True:

... try:

... x = int(raw_input("Please enter a number: "))

... break

... except ValueError:

... print "Oops! That was no valid number. Try again..."

...

try 语句按如下方式工作:

首先,执行try和except关键字之间的部分。

如果没有异常发生, except后面的部分不会执行。

如果有异常发生,停止执行后续语句,跳转到指定的异常处理部分。

如果异常没有处理,会传到外层的try,如果最终没有处理,如报出异常。

try语句可能包含多个except子句,分别处理不同的异常,只有一个分支执行。一个except同时处理多个异常,例如:

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子句,用于无异常时的执行。例如

import sys

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

使用else子句比在 try 子句中附加代码要好,因为这样可以避免try ... except截获不相关的异常。

异常时可能有相关值,即异常的参数,它和具体异常有关。

可以为 except子句指定变量,该变量绑定了异常实例及其参数中。异常实例定义了 str ()绑定了相关参数instance.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 printed directly

... x, y = inst.args

... print 'x =', x

... print 'y =', y

...

('spam', 'eggs')

('spam', 'eggs')

x = spam

y = eggs

如果异常有参数,在异常未处理的时候会在最后面打印出来。

函数中的异常也会处理。

>>> def this_fails():

... x = 1/0

...

>>> try:

... 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 "", line 1, in ?

NameError: HiThere

raise后面要接异常实例或异常类(继承自Exception类)。

简单一句raise可以重新最近的异常,但是因为不清晰不建议使用:

>>> try:

... raise NameError('HiThere')

... except NameError:

... print 'An exception flew by!'

... raise

...

An exception flew by!

Traceback (most recent call last):

File "", line 2, in ?

NameError: HiThere

用户异常

继承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 1, in ?

__main__.MyError: 'oops!'

该例重载了Exception默认的 init (),用value替换了args。

异常类中可以定义其他东西,但是通常建议简介,只加入属性信息,以供异常处理句柄提取。如果需要抛出几种不同的错误时,建议由异常基类和对应的异常子类:

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

大多数异常的命名都以 “Error” 结尾。

很多标准模块中都定义了自己的异常以方便报告错误。

finally

finally子句中的内容无论是否发生异常都会执行。

>>> try:

... raise KeyboardInterrupt

... finally:

... print 'Goodbye, world!'

...

Goodbye, world!

KeyboardInterrupt

无论如何都要执行finally才能退出, 多用于释放资源:

... try:

... result = x / y

... except ZeroDivisionError:

... print "division by zero!"

... else:

... print "result is", result

... finally:

... print "executing finally clause"

...

>>> divide(2, 1)

result is 2

executing finally clause

>>> divide(2, 0)

division by zero!

executing finally clause

>>> divide("2", "1")

executing finally clause

Traceback (most recent call last):

File "", line 1, in ?

File "", line 3, in divide

TypeError: unsupported operand type(s) for /: 'str' and 'str'

预定义清理

有些对象定义了标准的清理行为,无论是否成功,不需要该对象的时会起作用。下例打开文件并把内容打印到屏幕上:

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

print line,

这段代码的问题在于执行完毕后没有关闭文件,在大型应用程序就会出问题。 with语句可以确认相关资源及时释放:

with open("myfile.txt") as f:

for line in f:

print line,

本文地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值