回味Python2.7——笔记3

时间:2021-07-18 20:46:01

一、错误和异常

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
try
 ... except 语句可以带有一个 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__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__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() # 子类实例