一、错误和异常
1、异常处理
>>> 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 子句 (在
try
和except
关键字之间的部分)。 - 如果没有异常发生, except 子句 在
try
语句执行完毕后就被忽略了。 - 如果在 try 子句执行过程中发生了异常,那么该子句其余的部分就会被忽略。如果异常匹配于
except
关键字后面指定的异常类型,就执行对应的except
子句。然后继续执行try
语句之后的代码。 - 如果发生了一个异常,在
except
子句中没有与之匹配的分支,它就会传递到上一级try
语句中。如果最终仍找不到对应的处理语句,它就成为一个 未处理异常 ,终止程序运行,显示提示信息。
一个 try
语句可能包含多个 except 子句,分别指定处理不同的异常。至多只会有一个分支被执行。异常处理程序只会处理对应的 try 子句中发生的异常,在同一个 try
语句中,其他子句中发生的异常则不作处理。一个 except 子句可以在括号中列出多个异常的名字,例如:
... except (RuntimeError, TypeError, NameError): ... pass
最后一个 except 子句可以省略异常名称,以作为通配符使用。
while True: try: x=input('please enter the first number:') y=input('please enter the second number:') print 1.*x/y except: print 'something wrong happened! enter again!' else: break
please enter the first number:1 please enter the second number:w something wrong happened! enter again!2、 else
...
tryexcept
语句可以带有一个 else子句 ,该子句只能出现在所有 except 子句之后。当 try 语句没有抛出异常时,需要执行一些代码,可以使用这个子句。
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
意外的截获本来不属于它们保护的那些代码抛出的异常。
3、抛出异常
raise
语句允许程序员强制抛出一个指定的异常。
>>> raise NameError('HiThere') Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: HiThere
4、 用户自定义异常
在程序中可以通过创建新的异常类型来命名自己的异常(Python 类的内容请参见 类 )。异常类通常应该直接或间接的从 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 "<stdin>", line 1, in ? __main__.MyError: 'oops!'
5、finally
不管有没有发生异常, finally子句 在程序离开 try
后都一定会被执行。当 try
语句中发生了未被 except
捕获的异常(或者它发生在 except
或 else
子句中),在 finally
子句执行完后它会被重新抛出。 try
语句经由 break
,continue
或 return
语句退 出也一样会执行 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) 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 "<stdin>", line 1, in ? File "<stdin>", line 3, in divide TypeError: unsupported operand type(s) for /: 'str' and 'str'
二、类
使用class语句来创建一个新类,class之后为类的名称并以冒号结尾,如下实例:
class ClassName: '类的帮助信息' #类文档字符串 class_suite #类体
类的帮助信息可以通过ClassName.__doc__查看。
class_suite 由类成员,方法,数据属性组成。
class Student(object): def __init__(self, name, score): self.name = name self.score = score def print_score(self): print '%s: %s' % (self.name, self.score)
Python内置类属性
- __dict__ : 类的属性(包含一个字典,由类的数据属性组成)
- __doc__ :类的文档字符串
- __name__: 类名
- __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
- __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)
#!/usr/bin/python # -*- coding: UTF-8 -*- class Employee: '所有员工的基类' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary print "Employee.__doc__:", Employee.__doc__ print "Employee.__name__:", Employee.__name__ print "Employee.__module__:", Employee.__module__ print "Employee.__bases__:", Employee.__bases__ print "Employee.__dict__:", Employee.__dict__
Employee.__doc__: 所有员工的基类 Employee.__name__: Employee Employee.__module__: __main__ Employee.__bases__: () Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': 'xe6x89x80xe6x9cx89xe5x91x98xe5xb7xa5xe7x9ax84xe5x9fxbaxe7xb1xbb', '__init__': <function __init__ at 0x10a939578>}
类的继承
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。
#!/usr/bin/python # -*- coding: UTF-8 -*- class Parent: # 定义父类 parentAttr = 100 def __init__(self): print "调用父类构造函数" def parentMethod(self): print '调用父类方法' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "父类属性 :", Parent.parentAttr class Child(Parent): # 定义子类 def __init__(self): print "调用子类构造方法" def childMethod(self): print '调用子类方法 child method' c = Child() # 实例化子类 c.childMethod() # 调用子类的方法 c.parentMethod() # 调用父类方法 c.setAttr(200) # 再次调用父类的方法 c.getAttr() # 再次调用父类的方法
方法重写
如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法:
#!/usr/bin/python # -*- coding: UTF-8 -*- class Parent: # 定义父类 def myMethod(self): print '调用父类方法' class Child(Parent): # 定义子类 def myMethod(self): print '调用子类方法' c = Child() # 子类实例