Python之深入类和对象(鸭子类型与多态、抽象基类(abc模块)、类属性与实例属性、Python对象自省机制)

鸭子类型与多态
鸭子类型
  • 多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚"鸭子类型"
  • 态语言调用实例方法时不检查类型,只要方法存在,参数正确,就可以调用。这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
多态
  • 定义时的类型和运行时的类型不一样,就称为多态。
抽象基类(abc模块)
抽象基类介绍
  • 抽象基类(abstract base class,ABC):抽象基类就是类里定义了纯虚成员函数的类。纯虚函数只提供了接口,并没有具体实现。抽象基类不能被实例化(不能创建对象),通常是作为基类供子类继承,子类中重写虚函数,实现具体的接口。
  • 抽象基类就是定义各种方法而不做具体实现的类,任何继承自抽象基类的类必须实现这些方法,否则无法实例化。
抽象基类应用场景
  • 1.我们去检查某个类中是否有某种方法
  • 2.我们需要强调某个子类必须实现某些方法
1.检查某个类中是否有某种方法
  • 定义Demo类,类中含有__len__魔法方法
  • 导入抽象基类中的Sized类
class Demo(object):
    def __init__(self,elist):
        self.elist = elist

    def __len__(self):
        return len(self.elist)

d = Demo(["oldAmy", "ls"])

from collections.abc import Sized
print(isinstance(d, Sized))        # True  d是Sized子类
  • 查看Sized源码
    python安装路径下Lib中的隐藏文件_collections_abc.py
class Sized(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __len__(self):
        return 0

    @classmethod   
    def __subclasshook__(cls, C):
        if cls is Sized:
            return _check_methods(C, "__len__")
        return NotImplemented

注意:
- 抽象基类虽然可以成为别的类的父类,但是别的类并不会继承抽象基类的方法和属性

2.强制子类必须实现父类的方法

例子
- 定义父类Cache
封装CRUD方法。强制子类重写该方法。
- 定义子类redis

import abc
class CacheBase(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def dele(self,key):
        pass

    @abc.abstractmethod
    def crea(self,key,value):
        pass

class RedisBase(CacheBase):
    def dele(self,key,value):
        pass

    def crea(self,key):
        pass
r = RedisBase()  
type与isinstance区别
  • type 不考虑 继承关系
  • isinstance 考虑继承关系
类属性与实例属性
基本查找顺序
  • 对象是可以向上查找的,所以可以访问到类属性
    当对象自己有该实例属性时 ,则输出的是自己的
  • 类不能向下查找,所以只能访问到类属性
多继承查询顺序

继承关系如下,则属性查找顺序为?
在这里插入图片描述
实际上,python2.2(金典类)之前的算法:MRO算法,DFS(deep first search) 深度优先。
在这里插入图片描述
如下图,菱形继承,执行顺序如何?
在这里插入图片描述
在python2.2版本之后,引入BFS(广度优先)。
在python新式类,就引入了C3算法,通过className.__mro__来查看。
在这里插入图片描述

Python对象自省机制
  • 自省是通过一定的机制查询到对象的内部结构
  • python中比较常见的自省(introspection)机制(函数用法)有: dir(),type(), hasattr(), isinstance(),通过这些函数,我们能够在程序运行时得知对象的类型,判断对象是否存在某个属性,访问对象的属性。
super函数
  • 多继承下,super函数查询父类的顺序如何?
class A(object):
    def __init__(self):
        print("A")


class C(A):
    def __init__(self):
        print("B")
        super().__init__()


class B(A):
    def __init__(self):
        print("C")
        super().__init__()


class D(B,C):
    def __init__(self):
        print("D")
        super().__init__()


if __name__ == '__main__':
    d = D()
如何派生内置不可变类型并修改其实例化行为?
  • 自定义一种新类型的元组,将以下可迭代对象作为参数传入,并只保留其中int类型且值大于0的元素。
    IntTuple([2,-2,‘jr’,[‘x’,‘y’],4]) => (2,4)。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值