鸭子类型和多态
多态的概念是来源与Java和C#这一类强行语言中,而Python就是崇尚的"鸭子类型"
动态语言调用实例化对象类型,只要方法存在,参数正确就可以实现的,这就是动态语言的"鸭子类型"
所谓多态:就是定义类型时和运行类型时不一样就是多态
a = [1, 2] # list
b = [3, 4] # list
d = (5, 6) # tuple
e = {7, 8} # set # [1, 2, 8, 7] 集合是无序的
# 传参:self, iterable 什么是iterable iterable相当于是可迭代的对象
# 可迭代的对象可以通过for循环来取出来
a.extend(e) #可传e,b,d 这就是鸭子类型
print(a)
运行结果:
[1, 2, 8, 7]
class Person0(object):
def say(self):
print('Person0正在讲话')
class Person1(object):
def say(self):
print('Person1正在讲话')
class Person2(object):
def say(self):
print('Person2正在讲话')
Persons = [Person0, Person1, Person2]
for Person in Persons:
Person().say()
运行结果:
Person0正在讲话
Person1正在讲话
Person2正在讲话
抽象基类(abc模块)
抽象基类就是类里定义了纯虚成员函数的类。纯虚函数只提供了接口,并没有具有实现。抽象基类不能被实例化(不能创建对象),通常是作为基类提供子类继承函数,实现具体的接口
抽象基类就是定义各种方法而不是做具体实现的类,任何继承自抽象基类的类必须实现这写方法,否则无法实例化
应用场景
- 判断某个对象的类型
class Person(object):
def __init__(self, names):
self.names = names
def say(self):
print('我正在讲话')
def __len__(self):
return len(self.names)
# 实例化对象
p = Person(['钢铁侠', '蜘蛛侠', '绿巨人'])
print(len(p))
# hasattr 判断某个对象中含有该方法
print(hasattr(p, '__len__')) # 判读某个对象的实例
- 我们需要强制某个子类必须完成的某些方法
class Person(object):
def get(self,key):
raise ValueError # 主动抛出异常
def set(self,key,value):
raise ValueError
r = Person()
r.get('vale')
运行结果:
raise ValueError # 主动抛出异常
ValueError
improt abc模块
import abc
class Person(metaclass=abc.ABCMeta):
@abc.abstractmethod
def get(self,key):
raise ValueError # 主动抛出异常
@abc.abstractmethod
def set(self,key,value):
raise ValueError
r = Person()
# r.get('vale')
运行结果:
TypeError: Can't instantiate abstract class Person with abstract methods get
isinstance 和 type 的区别
isinstance
:会考虑类的继承
type
:不会考虑类的继承
class A(object):
pass
class B(A):
pass
class C(B):
pass
b = C()
print(isinstance(b, A)) # 判断isinstance是否会考虑继承的关系
print(type(b) is B) # is 判断的是内存地址值
# 运行结果
True
False
类变量和对象变量
class A():
aa = 1
def __init__(self, x, y):
self.x = x
self.y = y
a = A(1, 2)
# print(a.x, a.y, a.aa) # 实例化类对象可以向上查找
# print(A.x) # 调用类不能向下查找
A.aa = 22 # 相当于重新赋值
a.aa = 11 # 相当于添加了一个实例属性
print(A.aa)
print(a.aa)
# 运行结果
22
11
类属性和实例属性以及查找方法
MRO算法
MRO算法
Python2.2之前的算法:金典类
DFS(deep first search):A->B->D->C->E
Python2.2版本之后,引入了BFS(广度优先搜索)
BFS:A->B->C->D
在Python2.3之后,Python采用了C3算法
Python新式类继承的C3算法:C3算法的介绍
Python中的自省机制
什么是Python中的自省机制?
- 自省是通过一定的机制查询的对象的内容结构
- 自省相当于就是在生活中相当于是一种自我行为检测
Python中常见的自省机制函数
dir()、type()、isinstance()、hansater()
什么是dir()
:
- 简单来讲dir()相当于就是把这个对象中有的属性方法全部以列表的方式来存放到dir()中里面
print(dir(list))
#运行结果:
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
什么是type()
:?
- type()是用来判断当前的类型属于什么类型
a = 1
print(type(a))
运行结果:
<class 'int'>
什么是isinstance()
:?
- 用来判断一个对象是否是已知的数据类型
- 当结果是已知的数据类型时,返回的结果为True
- 当结果不是已知的数据类型时,返回的结果为False
a = 1
print(isinstance(a,int))
# 运行结果
True
什么是hasattr()
:?
- 判断某个对象中含有该方法
- 当含有该方法时,返回True
- 当没含有该方法时,返回False
class Person(object):
def __init__(self, names):
self.names = names
def say(self):
print('我正在讲话')
def __len__(self):
return len(self.names)
# 实例化对象
p = Person(['钢铁侠', '蜘蛛侠', '绿巨人'])
print(len(p))
# hasattr 判断某个对象中含有该方法
print(hasattr(p, '__len__')) # 判读某个对象的实例
运行结果:
3
True
super()函数
在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法,这就是super
存在的意义
重写了构造方法为什么还要使用super()?
减少代码的复用
扩展子类属性
有些属性父类中有的方法就不需要重写
# -*- coding: utf-8 -*-
# @Time : 2019/12/26 15:32
# @Author : 大数据小J
# @File : demo12-26.py
# @Software: PyCharm
class Animal():
def __init__(self, name, age, height):
self.name = name
self.age = age
self.height = height
def speak(self):
print('%s:说我的年龄是%d,身高是%s')
class Dog(Animal):
def __init__(self, name, age, height,sex):
super().__init__(name, age, height)
self.sex = sex
def speak(self):
print('%s:说我的年龄是%d,身高是%s,我是个%s' % (self.name, self.age, self.height,self.sex))
d = Dog('钢铁侠', 18, 180,'男')
d.speak()
运行结果:
钢铁侠:说我的年龄是18,身高是180,我是个男
super
的继承顺序
super是根据mro算法来实现继承顺序
class A():
def __init__(self):
print('A')
class B(A):
def __init__(self):
super().__init__()
print('B')
class C(A):
def __init__(self):
super().__init__()
print('C')
class D(B, C):
def __init__(self):
super().__init__()
print('D')
d = D()
print(D.__mro__)
运行结果:
A
C
B
D
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)