0x06 面向对象
类的定义
在我学过的其他语言当中,基本上也都包含有类这个概念,类在编程上也确实给了我们很大方便,尤其是在做工程比较大的项目时,类和对象的使用将会是的代码的结构更加清晰,功能更加模块化,便于修改和调试。 在Python中定义一个类只需要简单的两句:
1
2
class <类名>(父类名):
pass
这个类表面上看起来什么也没有实现,但实际上python中没有继承其他类的类会自动继承object类。
类的属性和方法
类中的方法和普通的函数有几个重要的区别:
- 方法的第一个参数必须是self,而且不能省略。
- 方法调用需要先实例化一个类对象。
- 方法需要缩进,表示属于类中的内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class MyClass:
myName = "Andy"
def __init__(self, x, y=0):
self.x = x
self.y = y
def calc(self):
return self.x + self.y
def changeName(self, name):
MyClass.myName = name
a = MyClass(3, 7)
b = MyClass(4, 7)
print(a.myName)
print(b.myName)
b.changeName("Jack")
print(a.myName)
print(b.myName)
a.myName = "Jane"
print(a.myName)
print(b.myName)
MyClass.myName = "King"
print(a.myName)
print(b.myName)
b.changeName("Jack")
print(a.myName)
print(b.myName)
运行结果:
Andy
Andy
Jack
Jack
Jane
Jack
Jane
King
Jane
Jack
类包含两种属性,实例属性和类属性。实例属性即同一个类的不同实例,他们的值是不相关的,如代码中的x,y变量,定义时使用self.属性名,调用时也这样用;而类属性则是所有实例共有的,直接在类中单独定义,使用时用“类名.类变量名”。但是注意,如果在实例中使用“实例对象名.类变量名”来修改类变量的值,那么这个类变量就不在具有“类”的属性了,而是成为了实例变量。
静态方法和类方法
和其他语言中静态方法类似,也就是在未实例化时也可以通过类名来调用静态方法,python中用@staticmethod来修饰,类方法和静态方法不同的一点是必须有默认参数cls,类方法用@classmethod来修饰。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyClass:
@staticmethod
def static_metd():
print "static method!"
@classmethod
def class_metd(cls):
print "class method!"
MyClass.static_metd()
MyClass.class_metd()
my = MyClass()
my.static_metd()
my.class_metd()
类的继承
类的继承格式在定义中已经说明,子类继承父类之后就拥有了父类的属性和方法,但是不能继承父类的私有属性和方法(前缀为两个下划线的),同时,子类也可以重载父类的方法。当子类继承多个父类时,如果父类中有同名的方法,但在类中使用时未指定父类名,那么python解释器将从从左至右依次搜索,即调用先继承的类中同名的方法。
0x07 异常处理
异常处理的一般结构如下:
1
2
3
4
5
6
7
8
9
10
11
try:
<语句> #可能产生异常的语句块
except <异常名1>:
<语句>
except <异常名2>:
<语句>
...
else:
<语句> #未触发异常则执行这里
finally:
<语句> #始终执行,一般释放资源等
Python中常见的异常如下:
| 异常名 | 描述 |
|---|---|
| AttributeError | 调用不存在的方法 |
| EOFError | 遇到文件末尾 |
| ImportError | 导入模块出错 |
| IndexError | 列表越界 |
| IOError | I/O引发异常 |
| KeyError | 使用字典中不存在的关键字 |
| NameError | 使用不存在的变量名 |
| TabError | 语句块缩进不正确 |
| ValueError | 搜索列表中不存在的值 |
| ZeroDivisionError | 除数为零 |
当然除了系统异常外,也可以在代码中使用“raise 异常名”手动抛出异常。另外还可以使用断言语句”assert <条件测试>,<异常附加数据>"抛出异常,此时可以捕获AssertionError异常。异常附加数据>条件测试>