导语:本文章记录了本人在学习Python基础之面向对象篇的重点知识及我的心得,打算入门Python的朋友们能够来一块儿学习并交流。
本文重点:安全
一、协议是Python中非正式的接口;
二、了解抽象基类的基本概念以及标准库中的抽象基类;
三、掌握抽象基类的使用方法。
协议:是Python中非正式的接口,是令Python这种动态类型语言实现多态的方式。
接口:泛指实体把本身提供给外界的一种抽象化物(能够为另外一实体),用以由内部操做分离出外部沟通方法,使其能被内部修改而不影响外界其余实体与其交互的方式。
类的接口:类实现或继承的公开属性(方法或数据属性),包括特殊方法,如__getitem__或__add__。app
协议是非正式的,只由文档和约定定义,不具有强制性。
以序列协议为例,假设咱们想实现迭代以及in运算,一般须要__iter__和__contains__方法,但事实上只实现__getitem__方法也能够。缘由在于当Python发现没有__iter__和__contains__可用时,会转而调用__getitem__方法设法让迭代和in运算符可用。
小结:部分实现协议是有用的。ssh
在运行时修改类或模块而不改动源码,从而实现目标协议接口的操做就是打猴子补丁。函数
鸭子类型(duck typing):不关注对象的类型,而是关注对象具备的行为(方法)。
鸭子类型像多态同样工做,可是没有继承。
在鸭子类型中,协议风格的接口与继承彻底没有关系,实现同一个协议的各个类是相互独立的。学习
白鹅类型(goose typing):只要cls是抽象基类,即cls的元类是abc.ABCMeta,就可使用isinstance(obj,cls)。spa
抽象基类(abstract base class,ABC):抽象基类就是类里定义了纯虚成员函数的类。纯虚函数只提供了接口,并无具体实现。抽象基类不能被实例化(不能建立对象),一般是做为基类供子类继承,子类中重写虚函数,实现具体的接口。
简言之,ABC描述的是至少使用一个纯虚函数的接口,从ABC派生出的类将根据派生类的具体特征,使用常规虚函数来实现这种接口。code
(1)collections.abc中抽象基类
collections.abc模块中各个抽象基类的UML类图以下所示:对象
Iterable 经过 __iter__ 方法支持迭代;
Container 经过__contains__ 方法支持 in 运算符;
Sized 经过 __len__ 方法支持len() 函数。
(2)numbers包中的数字塔
按照自上而下的线性结构,Number是位于最顶端的超类,详细排序以下:排序
例如,检查一个数是不是整数,可使用isinstance(x,numbers.Integral)。继承
声明抽象基类最简单的方式是继承abc.ABC或其余抽象基类:Class Student(abc.ABC)
注意:在Python3.0~3.3之间,继承抽象基类的语法是:Class Student(metaclass=abc.ABCMeta)。
在定义抽象基类的子类时,子类须要将继承的抽象基类中的抽象方法具体实现。
虚拟子类:指的是不经过继承而利用注册把一个类变成抽象基类的子类。
注册虚拟之类的方式是调用register方法,语法是@抽象基类名称.register。经注册后的虚拟子类能够被issubclass和isinstance等函数识别,可是注册的类不会从抽象基类中继承任何方法或属性。具体可经过类属性__mro__查看类的真实继承关系。
一、抽象基类中声明抽象类方法须要使用@abc.abstractmethod标记,而且在@abc.abstractmethod和def之间不能有其余装饰器。二、内省类的继承关系的方法:__subclasses__():返回类的直接子类列表,不含虚拟子类。__abcregistry:抽象基类独有的属性,是抽象类注册的虚拟子类的弱引用。三、__subclasshook__:令抽象基类识别没有进行子类化和注册的类,此方法在abc.Sized中有应用。