1.0 鸭子类型和多态
1.1 Python 比较崇尚鸭子类型,长得像鸭子,走路像鸭子,我们就可以称它是鸭子。
a = [1, 2]
b = [3, 4]
c = (5, 6)
d = "abc"
a.append(b)
a.append(c)
a.append(d)
输出结果:【1,2,3,4】
输出结果:【1,2,5,6】
输出结果:【1,2,a,b,c】
什么是动态语言:
是指数据类型的检查是在运行时做的。用动态类型语言编程时,不用给变量指定数据类型,该语言会在你第一次赋值给变量时,在内部记录数据类型
动态语言
调用方法时不检查类型,只要方法存在,参数正确,就可以调用。例如python,PHP,ASP
1.2 多态
鸭子类型也可以叫做多态,多态就是在定义时的类型,与使用时类型不一样,我们就称之为多态。
class A:
print("i am A")
class B:
print("i am B")
class C:
print("i am C")
l = [A,B,C] #三个类在这里是当做了变量
for i in l:
print(i)
2.0 抽象基类
2.1 抽象基类介绍
抽象基类
(abstract base class,ABC)就是类里面定义了纯虚成员函数的类,纯虚函数只提供了接口,并没有具体实现,抽象基类不能被实例化(不能创建对象),通常作为基类供子类继承,子类中重写虚函数,实现具体接口。
抽象基类
就是定义各种方法而不做具体实现的类。任何继承抽象基类的类,必须实现这些方法,否则无法实例化。
2.2 抽象基类的应用场景
检查某个类中是否含有某种方法
强调某个子类必须实现某些方法
例子1
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))
注意:注册的虚拟子类不会继承抽象基类的任何方法和属性
例子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()
3.0 isinstance与type的区别
区别:
isinstance 它的返回值是布尔值。
isinstance 它会考虑继承关系
class A:
pass
class B:
pass
li = B()
print(isinstance(li,B))返回True #判断li对象是否是B的实例化对象
print(isinstance(li,A))返回True #判断li对象是否是A的实例化对
type 的返回值是类型(对象的类型)
type 不考虑继承关系
#代码同上
print(type(li) is B)返回True
print(type(li) is A)返回False
print(f"a_id:{id(B)},b_id:{id(A)}")
is 比的是否是同一个对象
== 比的是值
4.0 类属性与实例属性
基本查找顺序
• 对象是可以向上查找的,所以可以访问到类属性
• 当对象自己有该实例属性时 ,则输出的是自己的
• 类不能向下查找,所以只能访问到类属性
多继承查询顺序
python2.2(金典类)之前的算法:MRO算法,DFS(deep first search) 深度优先。
在python2.2版本之后,引入BFS(广度优先)。
在python新式类,就引入了C3算法,通过className.__mro__来查看。
5.0 python的自省机制
自省是通过一定的机制查询到对象的内部结构
Python中比较常见的自省(introspection)机制(函数用法)有: dir(),type(), hasattr(), isinstance(),通过这些函数,我们能够在程序运行时得知对象的类型,判断对象是否存在某个属性,访问对象的属性。
6.0 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()
#print(D.__mro__)可以查看继承的顺序