补8.python之面相对象part.6(补充授权与继承的概念)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了补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(补充授权与继承的概念)的主要内容,如果未能解决你的问题,请参考以下文章

8.python之面相对象part.6(python类中的多态与多态性)

8.python之面相对象part.6(反射&__call__,__setattr__,__delattr__,__getattr__)

8.python之面相对象part.8(类装饰器)

8.python之面相对象part.8(__slots__属性)

8.python之面相对象part.2(特殊属性,类方法,静态方法)

8.python之面相对象part.9(初识元类part.1)