Python学习笔记 类的继承

让代码更有条理,这只是使用对象的好处之一。另一个更有用的好处是继承。可以通过指向一个已有的对象来定义对象,然后对他添加更多的属性和方法,从而定义一个新的对象。通过继承,可以不必重新编写代码来做同样的事情,只需要针对一些略微不同的项重新编写代码即可。

一、类的定义方法

这里通过一个实例来说明Python中类的定义方法。首先我们定义一个库存项类,它具有标题,说明和价格等基本属性,包含对应的方法。有一个书籍类从库存项类继承,并新定义了作者和格式两个属性,添加了几个新的方法,并重新定义一些函数等。

首先,先看看InventoryItem的基本的项。其他对象都是派生自这个对象。InventoryItem有title,description,price,ID属性,如果打印它,返回该项的名称。如果想查看两个项是否相等,它比较库存ID,除此之外,还有三个函数,分别用来修改价格,说明和名称。

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
class InventoryItem(object):
"""定义一个库存项基类,包含title,description,price三个属性,含有
change_description,change_price,change_title三个方法
"""
def __init__(self,title,description,price,store_id):
self.title=title #标题
self.description=description #说明
self.price=price #价格
self.store_id=store_id #库存编号

#用来返回输出值的函数
def __str__(self):
return self.title

#用来判断对象是否相等的函数
def __eq__(self,other):
if self.store_id==other.store_id:
return True
else:
return False

#change_description方法,用来修正对象的说明
def change_description(self,description=""):
if not description: #没有输入描述参数
description=raw_input("Please give me a description:")
self.description=description

#change_price方法,用来修正对象的价格
def change_price(self,price=-1):
while price<0:
price=raw_input("Please input the new price:")
try:
price=float(price)
break
except:
print "I'm sorry, but {} isn't valid.".format(price)
self.price=price

#change_title方法,用来修正对象的标题
def change_title(self,title=""):
if not title:
title=raw_input("Please give me the a new title:")
self.title=title

现在有一个基类,我们接下来创建一个继承于它的新类Book。把类的名称放在通常放置对象的圆括号中,从而告诉Python,想要继承自该类。所以函数声明需要用“class Book(InventoryItem):”,而不是“class Book(object):”。
这里的Book类新定义了两个属性:format和author,打印该对象时,返回标题和作者(基类中返回标题),判断两个Book类的对象是否相等时,同时比较标题和作者,若二者均相等时,则返回True,除此之外,还有两个方法,用来改变format和author属性。

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
class Book(InventoryItem):   #将基类名称作为放置对象,表示继承
"""定义一个Book类,该类继承于InventoryItem类,并添加了author和format两个属性,
添加了change_author,change_format方法,并重新定义了一个print方法用来输出
"""
def __init__(self,title,description,price,format,author,store_id):
super(Book,self).__init__(title=title,description=description,price=price,store_id=store_id)
self.format=format
self.format=author

def __str__(self): #打印时返回标题和作者
book_line="{title} by {author}".format(title=self.title,author=self.author)
return book_line

def __eq__(self,other): #判断两个Book类的对象是否相等
if self.title==other.title and self.author==other.author:
return True
else:
return False

def change_format(self,format):
if not format:
format=raw_input("Please input the new format:")
self.format=format

def change_author(self,author):
if not author:
author=raw_input("Please input the author:")
self.author=author

这里子类中的init()方法中,有一个super()方法,它是Python中一个特殊的函数,它告诉Python调用父类中的一个函数。通过这个方法,我们不需要重复写同样的代码。同时,子类中的eq()和str()方法覆盖了基类中对应的方法。

下面我们对上述类做个简单的测试:

1
2
3
4
5
6
7
8
9
10
11
hamlet=Book(title="Hamlet",description="A Dane has a bad time.",price=5.99,format="paperback",store_id="29382918",author="William Shakespears")
hamlet_hardback=Book(title="Hamlet",description="A Dane has a bad time.",price=5.99,format="paperback",store_id="29382918",author="William Shakespears")
macbeth=Book(title="Macbeth",description="Don't listen to strange ladies on the side of the road.",price=4.99,format="paperback",store_id="23928932",author="William Shakespears")

hamlet==hamlet_hardback
hamlet==macbeth
print(hamlet)
hamlet.change_description("The trouble with remarriage.")
macbeth.change_format(format="audiobook")
macbeth.format
hamlet.description

其输出结果为:

1