首页 > 代码库 > 补8.python之面相对象part.6(补充授权与继承的概念)
补8.python之面相对象part.6(补充授权与继承的概念)
一.什么是python中对类的“包装”。
(简单来说,包装就是通过类继承的特性为类增加或者修改类中原有的功能)
举个例子,python内部提供了很多标准的数据类型,以及很多的内置方法,在有一些场景下,我们需要基于标准数据类型去定制自己所需要的数据类型,新增或者改写一些类的方法,在做这种操作的时候,就需要用到类继承相关的知识。(python自带的标准类也可以通过“包装”这种方式来进行二次加工。)
例子1:给python的list列表类增加一个功能,这个功能可以查看列表中最中间的元素,并且修改list类中原有的append方法,在使用append给一个列表追加元素的时候,追加的数据类型只允许是字符串,不可以是数字。
现在要完成例子1的两个需求,就可以通过“包装”(继承)方式来实现。
#!/usr/bin/python2.7
# -*- coding:utf-8 -*-
class new_list(list): #新定义了一个类叫new_list这个类继承了python内置的list类
def append(self, p_object): #定义一个append方法,将从list类中继承到的append方法做一个修改
if not isinstance(p_object,str): #判断传入的值是否是字符串类型
print "非字符串不能使用append添加到这个新式列表中" #如果不是打印这行文字
else:
super(new_list,self).append(p_object) #如果是字符串类型,那么使用super关键字,去调用new_list的父类,list类中的append方法。
def show_mid(self): #这个是新增的方法。
index = int(len(self) / 2)
print self[index]
接下来测试下new_list这个类的功能。
nl1 = new_list() #使用new_list类初始化一个实例,实例的名字为nl1。
接下来给nl1这个列表添加一个非字符串类型的元素,看看会有什么效果。
nl1.append(123) #添加一个非字符串的元素。
输出:
非字符串不能使用append添加到这个新式列表中
接下来,传入几个字符串类型的元素。
nl1 = new_list()
nl1.append("one")
nl1.append("two")
nl1.append("three")
nl1.append("four")
nl1.append("five")
print nl1
输出:
[‘one‘, ‘two‘, ‘three‘, ‘four‘,‘five‘]
#字符串类型的元素被成功添加到了列表中。
从例子中可以看出,new_list父类list的append方法的功能成功被修改了。
接下来测试下在list基础上新增的show_mid方法。
print nl1
输出:
[‘one‘, ‘two‘, ‘three‘, ‘four‘,‘five‘]
nl1.show_mid()
输出:
three #成功打印出了列表中最中间的元素。
二.什么是授权?
授权是“包装”的一个特性,当要“包装”一个类的时候,通常是对已经存在的类做一些定制,对已经存在的类的功能做修改(添加,删除,修改),不过“授权”并不是通过继承来实现的,它和继承一点关系都没有,授权是通过覆盖__getattr__方法来实现的。
(也可以将“授权”理解为另一种“包装”类的形式)
什么时候需要用到授权呢?
拿python中的文件对象来举例吧,我们都知道,在python中文件也是个对象,如果想实例化出一个文件对象,需要使用open函数来完成,现在有个需求,就是自己定义一个对文件操作的类,并且修改这个类的write方法,在通过自己定义的这个类写文件的时候,把当前时间也写到文件中(也就是给wirte方增加一个写入当前时间的功能)。
#!/usr/bin/python2.7
# -*- coding:utf-8 -*-
import time
class file_handle(object): #自己定义了一个处理文件的类file_handle。
def __init__(self,file_path,mode="r"): #通过构造方法通过open函数创建文件句柄
self.file_open = open(file_path,mode)
def write(self,line):
date = time.strftime(‘%Y-%m-%d %T‘)
self.file_open.write("%s %s" %(date,line)) #调用文件句柄的write方法,将内容写到文件。
def __getattr__(self, item): #当一个方法从类中找不到的时候,就会触发__getattr__方法。
#当read方法,write方法都找不到的时候,就会触发这个方法。
return getattr(self.file_open,item) #通过getattr函数进行反射查找出文件句柄原有的功能。
f1 = file_handle(‘a.txt‘,mode="r")
在file_handle这个类中,并没有定义read方法,我们来试试看,是否可以读出文件的内容。
f1 = file_handle(‘a.txt‘,mode="r") #初始化对象,并传参,通过自己创建的这个类去打开a.txt这个文件。
f1.read()
输出:
hello world\n
#成功调用了文件对象的read方法,并且没有使用继承的方式。
#接着在试着调用wirte方法在文件中写内容,看看文件对象原有的write功能是否有被改变。
f1 = file_handle(‘a.txt‘,mode="w")
f1.seek(0)
f1.write("aaaaaaaaaaa\n")
f1.write("bbbbbbbbbbb\n")
f1.flush()
#在文件中写入了两行内容,接下来打开文件看看内容和时间是否有被写到文件内部。
文件内容如下:
2017-04-19 20:59:23 aaaaaaaaaaa
2017-04-19 20:59:23 bbbbbbbbbbb
#成功的通过了授权的方式修改了文件对象的write功能。
本文出自 “reBiRTH” 博客,请务必保留此出处http://suhaozhi.blog.51cto.com/7272298/1917520
补8.python之面相对象part.6(补充授权与继承的概念)