python 全栈开发,Day21(抽象类,接口类,多态,鸭子类型)
一、昨日复习
派生方法和派生属性
super 只有在子父类拥有同名方法的时候,
想使用子类的对象调用父类的方法时,才使用super
super在类内 : super().方法名(arg1,..)
指名道姓 :父类名.方法名(self,arg1,..)
多继承 钻石继承
经典类 python2 不继承object
查找名字遵循深度优先遍历算法
新式类 python3中都是新式类 在py2中继承object
查找名字遵循广度优先遍历算法
当一个节点可以在深度广度上都有机会被访问到的时候
优先从广度上查找
类名.mro()方法可以查看广度优先的顺序
super()的作用:在广度优先中查看当前这个类的上一个节点
在py2中super必须传参数 super(子类名,self).方法名(arg...)
进入正题
java 编程原则和设计模式
《设计模式》 这本书,是从从java中演变出来的,它的程序设计 具有里程碑意义的设计方式
单例模式
一个类只有一个实例
《算法导论》 也是一本书,主要是计算的方法 时间和空间的问题 权威通用
java
面向对象
java不能多继承
编程原则
python
开放封闭原则
开放 对扩展是开放的
封闭 对修改是封闭的
依赖倒置原则
接口隔离原则
先来讲开放原则:
看下面一个类,只有一个方法
class Student(object):
def show_info(self):pass
它可以在加一个方法
class Student(object):
def show_info(self):pass
def show_score(self):pass
它可以任意的扩展方法,对扩展是开放的
再来讲封闭原则:
修改一个方法名
class Student(object):
def show_info2(self):pass
def show_score(self):pass
但是不建议直接修改方法名,因为可能有程序在调用,如果修改了,调用的地方,就会报错。
这就是封闭原则,比如已经写完的程序代码是不允许修改的
一、抽象类
什么是抽象类
与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化
为什么要有抽象类
如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。
从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。
从实现角度来看,抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的,即将揭晓答案
举例,支付宝和qq支付
class Alipay(object):
def pay(self,money):
print('使用支付宝支付了%s元'%money) class QQpay(object):
def pay(self,money):
print('使用qq支付了%s元'%money) a = Alipay()
a.pay(100)
b = QQpay()
b.pay(100)
执行输出:
使用支付宝支付了100元
使用qq支付了100元
支付宝和qq有相同的方法,可不可以定义一个方法,统计实现呢?
class Alipay(object):
def pay(self,money):
print('使用支付宝支付了%s元'%money) class QQpay(object):
def pay(self,money):
print('使用qq支付了%s元'%money) class Wechatpay(object):
def fuqian(self,money):
print('使用微信支付了%s元' % money) def pay(obj,money): # 统一支付方法
'''
:param obj: 实例化对象
:param money: 金钱
:return: 使用xx支付了xx元
'''
obj.pay(money) # 执行实例化对象的类方法pay a = Alipay()
#a.pay(100)
b = QQpay()
#b.pay(100) pay(a,100) # 传入一个对象和100
pay(b,100)
执行输出:
使用支付宝支付了100元
使用qq支付了100元
这个统一的方法,叫做归一化设计
归一化设计:不管是哪一个类的对象,都调用同一个函数去完成相似的功能
归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合
比如python的len方法,它可以接收很多参数类型,返回对象(字符、列表、元组等)长度或项目个数
len()和__len__()
只有一个类中实现了__len__()方法,才能使用len()方法
比如下面的例子
a = '123'
print(a.__len__())
执行输出:3
回到上面支付宝的例子:
有一个新来的程序员接到上级指示,要求做一个微信支付的功能
class Wechatpay(object):
def fuqian(self,money):
print('使用微信支付了%s元' % money)
知道支付宝和qq实例一下,直接直接pay方法就可以了。他也复制了一下
a = Alipay()
#a.pay(100)
b = QQpay()
#b.pay(100)
w = Wechatpay() pay(a,100) # 传入一个对象和100
pay(b,100)
pay(w,100)
执行报错:
AttributeError: 'Wechatpay' object has no attribute 'pay'
提示没有pay方法。why?
把fuqian改成pay就可以了
为了避免这种问题,创建一个规范类Payment
然后每个类继承一下
class Payment(object): # 抽象类 接口类 规范
def pay(self):pass class Alipay(Payment):
def pay(self,money):
print('使用支付宝支付了%s元'%money) class QQpay(Payment):
def pay(self,money):
print('使用qq支付了%s元'%money) class Wechatpay(Payment):
def fuqian(self,money):
print('使用微信支付了%s元' % money)
Payment不需要pay的代码,只需要子类实现即可
Payment没有任何代码实现,必须要求子类有同名的方法名
那么Wechatpay实例化的时候,不会报错,执行pay方法直接报错
w = Wechatpay()
w.pay(100)
TypeError: pay() takes 1 positional argument but 2 were given
假如有5个类,需要规范一下,怎么保证,实例化的时候,有不规范的,直接报错呢?
需要用到abc模块
from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta): # 抽象类 接口类 规范和约束 metaclass指定的是一个元类
@abstractmethod
def pay(self):pass # 抽象方法,python从语法上支持的规范类 class Alipay(Payment):
def pay(self,money):
print('使用支付宝支付了%s元'%money) class QQpay(Payment):
def pay(self,money):
print('使用qq支付了%s元'%money) class Wechatpay(Payment): # 继承了Payment类,就必须去实现被abstractmethod装饰的方法
def fuqian(self,money):
print('使用微信支付了%s元' % money) w = Wechatpay() # 实例化
执行报错:
TypeError: Can't instantiate abstract class Wechatpay with abstract methods pay
抽象类和接口类做的事情 :建立规范
制定一个类的metaclass是ABCMeta,那么这个类就变成了一个抽象类(接口类),这个类的主要功能就是建立一个规范
抽象类中所有被abstractmethod装饰的方法都必须被继承的子类实现
如果不实现,那么在实例化阶段将会报错
无论是抽象类还是接口类metaclass=ABCMeta 都不可以被实例化
p = Payment() 报错
如果抽象类没有abstractmethod装饰器,那么这个方法,子类不需要实现
把fuqian改成pay就可以实例化了
依赖倒置原则
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程
解释一下, 依赖倒置原则
Payment是高层模块,Wechatpay是底层类。Wechatpay只能依赖Payment,Payment不能依赖Wechatpay,因为它是底层模块。
Payment是抽象类,它定义了pay方法,具体实现的逻辑,它不需要写,由子类来完成。
写代码并不是为了实现功能,而是在实现功能的前提下,规划化代码。
二、接口类
什么叫接口
python里面没有接口的概念,那接口是哪儿来的概念呢?从java里面来的
接口类:定义一个接口对继承类进行约束,接口里有什么方法,继承类就必须有什么方法,接口中不能有任何功能代码
比如动物园里面的动物
会游泳,走路,爬树,飞行的动物,比如
老虎,青蛙,天鹅,猴子
定义几个动物:
class Tiger(object): # 老虎
def walk(self):pass # 走路
def swim(self):pass # 游泳
class Monkey(object): # 猴子
def walk(self):pass
def climb(self):pass # 爬树
class Swan(object): # 天鹅
def walk(self): pass
def swim(self): pass
def fly(self):pass # 飞行
def cal_flying_seeed(self):pass # 计算飞行速度
def cal_flying_height(self):pass # 计算飞行高度
观察上面的代码,技能重复了。这样写,容易丢失方法。
加一个鹦鹉,但是它少了一些飞行类的方法
class Parrot(object):
def fly(self):pass
def cal_flying_seeed(self): pass
怎么解决这个问题呢?定义一个抽象类A
from abc import ABCMeta,abstractmethod
class A(metaclass=ABCMeta):
@abstractmethod
def fly(self): pass
@abstractmethod
def cal_flying_seeed(self): pass
@abstractmethod
def cal_flying_height(self): pass
class Tiger(object): # 老虎
def walk(self):pass # 走路
def swim(self):pass # 游泳
class Monkey(object): # 猴子
def walk(self):pass
def climb(self):pass # 爬树
class Swan(A): # 天鹅
def walk(self): pass
def swim(self): pass
def fly(self):pass # 飞行
def cal_flying_seeed(self):pass # 计算飞行速度
def cal_flying_height(self):pass # 计算飞行高度
class Parrot(A):
def fly(self):pass
def cal_flying_speed(self): pass Parrot()
执行输出:
TypeError: Can't instantiate abstract class Parrot with abstract methods cal_flying_height
鹦鹉实例化时,报错,找不到方法cal_flying_height
这样就约束了飞行动物的方法
所有会走的动物,具有一些会走的动物特性
对于爬行动物,不能继承A
所以需要再定义一抽象类
from abc import ABCMeta,abstractmethod
class FlyAnimal(metaclass=ABCMeta): # 飞行
@abstractmethod
def fly(self):pass
@abstractmethod
def cal_flying_speed(self):pass
@abstractmethod
def cal_flying_height(self):pass
class WalkAnimal(metaclass=ABCMeta): # 走路
@abstractmethod
def walk(self):pass
class SwimAnimal(metaclass=ABCMeta): # 游泳
@abstractmethod
def swim(self):pass
class Tiger(WalkAnimal,SwimAnimal): # 老虎,继承走路和游泳
def walk(self):pass # 走路
def swim(self):pass # 游泳
class Monkey(WalkAnimal): # 猴子
def walk(self):pass
def climb(self):pass # 爬树
class Swan(FlyAnimal,WalkAnimal,SwimAnimal): # 天鹅,继承飞行,走路,游泳
def walk(self): pass
def swim(self): pass
def fly(self):pass # 飞行
def cal_flying_speed(self):pass # 计算飞行速度
def cal_flying_height(self):pass # 计算飞行高度
class Parrot(FlyAnimal): # 鹦鹉,继承飞行
def fly(self):pass
def cal_flying_speed(self): pass
def cal_flying_height(self): pass #实例化
Tiger()
Monkey()
Swan()
Parrot()
执行输出,就没有报错了。
接口隔离原则:
使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口。
解释:
在上面的动物园的例子中:
所有会飞的动物 具有一些会飞的动物的特性
所有会走的动物 具有一些会走的动物的特性
不能使用单一的总接口来完成,所以需要定义多个抽象类,同时,不需要的接口不要给底层类继承。
总结:
接口类的作用:
在java中,能够满足接口隔离原则,且完成多继承的约束
而在python中,满足接口隔离原则,由于python本身支持多继承,所以就不需要接口的概念了
抽象类和接口类
在python中
并没有什么不同,都是用来约束子类中的方法的
只要是抽象类和接口类中被abstractmethod装饰的方法,都需要被子类实现
需要注意的是,当多个类之间有相同的功能也有不同的功能的时候,应该采用多个接口类来进行分别的约束
在java中
抽象类和接口截然不同
抽象类的本质还是一个类 是类就必须遵循单继承的规则,所以一个子类如果被抽象类约束,那么它只能被一个父类控制
当多个类之间有相同的功能也有不同的功能的时候 java只能用接口来解决问题
说一些题外话
面试的时候
他可能会问:什么是抽象类?什么是接口类?
抽象类 是python中定义类的一种规范,用来约束子类中的方法的。被abstractmethod装饰的方法,子类必须实现,否则实例化时报错。
接口类 满足接口隔离原则,且完成多继承的约束。如果不按照规范,在调用方法时,报错。
在公司类写代码的时候
如果遇到抽象类 记得按照抽象类中的规范一一实现对应的方法
三、多态
java c++ c—— 强类型语言
相同数据类型之间做运算
def func(int a):pass
func('a')
shell语言 —— 弱类型语言
1+'1'
def func(a):pass
1 'a' [1,2,3] ()
介于 强类型 与 弱类型之间 —— python 动态强类型语言
相同数据类型之间做运算
def func(a):pass
多态指的是一类事物有多种形态
动物有多种形态:人,狗,猪
import abc
class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
@abc.abstractmethod
def talk(self):
pass class People(Animal): #动物的形态之一:人
def talk(self):
print('say hello') class Dog(Animal): #动物的形态之二:狗
def talk(self):
print('say wangwang') class Pig(Animal): #动物的形态之三:猪
def talk(self):
print('say aoao')
多态性
什么是多态动态绑定(在继承的背景下使用时,有时也称为多态性)
多态性是指在不考虑实例类型的情况下使用实例
class Payment:
def pay(self):pass class QQpay(Payment):
def pay(self, money):
print('使用qq支付了%s元'%money) class Wechatpay(Payment):
def pay(self, money):
print('使用微信支付了%s元'%money) def pay(pay_obj,money): # 统一支付方法
'''
:param pay_obj: 实例化对象
:param money: 金钱
:return: 使用xx支付了xx元
'''
pay_obj.pay(money) # 执行实例化对象的类方法pay qq = QQpay()
we = Wechatpay() pay(qq, 100)
pay(we, 200)
执行输出:
使用qq支付了100元
使用微信支付了200元
通过执行pay函数,传入不同的参数返回不同的结果,这就是多态
一种接口,多种实现
上面的例子是面向过程的函数加面向对象,实现的。整形效果不好,把函数放到父类里面
class Payment:
@staticmethod
def pay(pay_obj,money): # 静态方法.需要通过类名+方法名来调用这个方法
'''
统一支付方法
:param pay_obj: 实例化对象
:param money: 金钱
:return: 使用xx支付了xx元
'''
pay_obj.pay(money) class QQpay(Payment):
def pay(self, money):
print('使用qq支付了%s元'%money) class Wechatpay(Payment):
def pay(self, money):
print('使用微信支付了%s元'%money) qq = QQpay()
we = Wechatpay() Payment.pay(qq, 100)
Payment.pay(we, 200)
执行输出:
使用qq支付了100元
使用微信支付了200元
无论是python的2.*还是3.* : 天生自带多态效果
多态 通过继承实现
在python中不需要刻意实现多态,因为python本身自带多态效果
在python2种,虽然没有有object类,但是它有一个类似于object类的属性。它内嵌在解释器里面,你看不到,它没开放。python3开放了,它就是objcet
四、鸭子类型
逗比时刻:
Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’
python程序员通常根据这种行为来编写程序。例如,如果想编写现有对象的自定义版本,可以继承该对象
也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。
例1:利用标准库中定义的各种‘与文件类似’的对象,尽管这些对象的工作方式像文件,但他们没有继承内置文件对象的方法
例2:序列类型有多种形态:字符串,列表,元组,但他们直接没有直接的继承关系
#二者都像鸭子,二者看起来都像文件,因而就可以当文件一样去用
class TxtFile:
def read(self):
pass def write(self):
pass class DiskFile:
def read(self):
pass
def write(self):
pass
在Python不崇尚通过继承来约束
比如
[].index()
''.index()
().index()
列表、字符串、元组都有index方法
查看index源码
def index(self, value, start=None, stop=None): # real signature unknown; restored from __doc__
"""
L.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.
"""
return 0
index这个名字是约定俗成的,它不是代码级别约束的
总结:
多态和鸭子类型
多态 通过继承实现
java 在一个类之下发展出来的多个类的对象都可以作为参数传入一个函数或者方法
在python中不需要刻意实现多态,因为python本身自带多态效果
鸭子类型
不是通过具体的继承关系来约束某些类中必须有哪些方法名
是通过一种约定俗成的概念来保证在多个类中相似的功能叫相同的名字
练习题:
一、:定义一个学生类。有下面的类属性:
1 姓名
2 年龄
3 成绩(语文,数学,英语)[每课成绩的类型为整数]
类方法:
1 获取学生的姓名:get_name() 返回类型:str
2 获取学生的年龄:get_age() 返回类型:int
3 返回3门科目中最高的分数。get_course() 返回类型:int
写好类以后,可以定义2个同学测试下:
zm = Student('zhangming',20,[69,88,100])
返回结果:
zhangming
20
100 二、定义一个字典类:dictclass。完成下面的功能:
dict = dictclass({你需要操作的字典对象})
1.
删除某个key
del_dict(key)
2.
判断某个键是否在字典里,如果在返回键对应的值,不存在则返回
"not found"
get_dict(key)
3.
返回键组成的列表:返回类型;
(list)
get_key()
4.
合并字典,并且返回合并后字典的values组成的列表。返回类型: (list)
update_dict({要合并的字典}) 三、定义一个列表的操作类:Listinfo
包括的方法: 1 列表元素添加: add_key(keyname) [keyname:字符串或者整数类型]
2 列表元素取值:get_key(num) [num:整数类型]
3 列表合并:update_list(list) [list:列表类型]
4 删除并且返回最后一个元素:del_key() list_info = Listinfo([44,222,111,333,454,'sss','333']) 四、定义一个集合的操作类:Setinfo 包括的方法: 1 集合元素添加: add_setinfo(keyname) [keyname:字符串或者整数类型]
2 集合的交集:get_intersection(unioninfo) [unioninfo :集合类型]
3 集合的并集: get_union(unioninfo)[unioninfo :集合类型]
4 集合的差集:del_difference(unioninfo) [unioninfo :集合类型]
set_info = Setinfo(你要操作的集合)
答案:
一、
1.创建一个文件Student.py,写类的雏形,内容如下:
class Student(object):
def __init__(self, name,age,score):
self.name = name
self.age = age
self.score = score def get_name(self):pass
def get_age(self): pass
def get_course(self): pass
2.完善类方法,完成第一个需求
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score def get_name(self): # 获取学生的姓名
return self.name def get_age(self): pass def get_course(self): pass xm = Student('xiaoming', 20, [69, 88, 100])
print(xm.get_name())
执行输出:
xiaoming
3.完成第二个需求
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score def get_name(self): # 获取学生的姓名
return self.name def get_age(self): # 获取学生的年龄
return self.age def get_course(self): pass xm = Student('zhangming', 20, [69, 88, 100])
print(xm.get_age())
执行输出:
20
4.完成第三个需求
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score def get_name(self): # 获取学生的姓名
return self.name def get_age(self): # 获取学生的年龄
return self.age def get_course(self): # 返回3门科目中最高的分数
return '{}\n{}\n{}'.format(self.name,self.age,max(self.score)) zm = Student('zhangming',20,[69,88,100])
print(zm.get_course())
执行输出:
zhangming
20
100
二、
1.准备类的雏形
class dictclass(object):
def __init__(self,dic):
self.dic = dic
def del_dict(self):pass
def get_dict(self): pass
def get_key(self): pass
def update_dict(self): pass
2.完成第一个需求
class dictclass(object):
def __init__(self,dic):
self.dic = dic
def del_dict(self,key): # 删除key
return self.dic.pop(key)
def get_dict(self): pass
def get_key(self): pass
def update_dict(self): pass dict = dictclass({'name':'布兰妮','age':'23','sex':'F'})
dict.del_dict('name') # 执行删除方法
print(dict.__dict__['dic']) #查看字典的值
执行输出:
{'age': '23', 'sex': 'F'}
3.完成第二个需求
class dictclass(object):
def __init__(self,dic):
self.dic = dic
def del_dict(self,key): # 删除key
return self.dic.pop(key)
def get_dict(self,key): #获取key的值
return self.dic.get(key,'not found')
def get_key(self): pass
def update_dict(self): pass dict = dictclass({'name':'布兰妮','age':'23','sex':'F'})
print(dict.get_dict('name')) # 获取名字
print(dict.get_dict('height')) # 获取一个不存在的key,比如height
执行输出:
布兰妮
not found
4.完成第三个需求
class dictclass(object):
def __init__(self,dic):
self.dic = dic
def del_dict(self,key): # 删除key
return self.dic.pop(key)
def get_dict(self,key): # 获取key的值
return self.dic.get(key,'not found')
def get_key(self): # 返回键组成的列表
return list(self.dic) def update_dict(self): pass dict = dictclass({'name':'布兰妮','age':'23','sex':'F'})
print(dict.get_key())
执行输出:
['sex', 'name', 'age']
5.完成第四个需求
class dictclass(object):
def __init__(self,dic):
self.dic = dic
def del_dict(self,key): # 删除key
return self.dic.pop(key)
def get_dict(self,key): # 获取key的值
return self.dic.get(key,'not found')
def get_key(self): # 返回键组成的列表
return list(self.dic)
def update_dict(self,key): # 合并字典
self.dic.update(key)
return list(self.dic.values()) dict = dictclass({'name':'布兰妮','age':'23','sex':'F'})
print(dict.update_dict({'height':172,'hobby':'sing'}))
执行输出:
['F', 172, '布兰妮', 'sing', '23']
三、
1.准备类的雏形
class Listinfo(object):
def __init__(self,li):
self.li =li
def add_key(self,keyname):pass
def get_key(self,num):pass
def update_list(self,list):pass
def del_key(self):pass
2.完成第一个需求
class Listinfo(object):
def __init__(self,li):
self.li = li
def add_key(self,keyname): # 列表元素添加
self.li.append(keyname)
return self.li
def get_key(self,num): pass
def update_list(self,list):pass
def del_key(self):pass list_info = Listinfo([44,222,111,333,454,'sss','333'])
print(list_info.add_key(555))
执行输出:
[44, 222, 111, 333, 454, 'sss', '333', 555]
3.完成第二个需求
class Listinfo(object):
def __init__(self,li):
self.li = li
def add_key(self,keyname): # 列表元素添加
self.li.append(keyname)
return self.li
def get_key(self,num): # 列表元素取值
return self.li[num]
def update_list(self,list):pass
def del_key(self):pass list_info = Listinfo([44,222,111,333,454,'sss','333'])
print(list_info.get_key(2))
执行输出:
111
4.完成第三个需求
class Listinfo(object):
def __init__(self,li):
self.li = li
def add_key(self,keyname): # 列表元素添加
self.li.append(keyname)
return self.li
def get_key(self,num): # 列表元素取值
return self.li[num]
def update_list(self,list): # 列表合并
new_list = self.li + list
return new_list
def del_key(self):pass list_info = Listinfo([44,222,111,333,454,'sss','333'])
print(list_info.update_list([5,2,1]))
执行输出:
[44, 222, 111, 333, 454, 'sss', '333', 5, 2, 1]
4.完成第四个需求
class Listinfo(object):
def __init__(self,li):
self.li = li
def add_key(self,keyname): # 列表元素添加
self.li.append(keyname)
return self.li
def get_key(self,num): # 列表元素取值
return self.li[num]
def update_list(self,list): # 列表合并
new_list = self.li + list
return new_list
def del_key(self): # 删除并且返回最后一个元素
return self.li.pop() list_info = Listinfo([44,222,111,333,454,'sss','333'])
print(list_info.del_key())
执行输出:333
四、
1.准备类的雏形
class Setinfo(object):
def __init__(self,gather):
self.gather = gather
def add_setinfo(self,keyname):pass
def get_intersection(self,unioninfo):pass
def get_union(self,unioninfo):pass
def del_difference(self,unioninfo):pass
2.完成第一个需求
class Setinfo(object):
def __init__(self,gather):
self.gather = gather
def add_setinfo(self,keyname): # 集合元素添加
self.gather.add(keyname)
return self.gather
def get_intersection(self,unioninfo):pass
def get_union(self,unioninfo):pass
def del_difference(self,unioninfo):pass set_info = Setinfo({1,2,3})
print(set_info.add_setinfo(4))
执行输出:
{1, 2, 3, 4}
3.完成第二个需求
class Setinfo(object):
def __init__(self,gather):
self.gather = gather
def add_setinfo(self,keyname): # 集合元素添加
self.gather.add(keyname)
return self.gather
def get_intersection(self,unioninfo): # 集合的交集
return self.gather & unioninfo
def get_union(self,unioninfo):pass
def del_difference(self,unioninfo):pass set_info = Setinfo({1,2,3})
print(set_info.get_intersection({3,4,5}))
执行输出:
{3}
4.完成第三个需求
class Setinfo(object):
def __init__(self,gather):
self.gather = gather
def add_setinfo(self,keyname): # 集合元素添加
self.gather.add(keyname)
return self.gather
def get_intersection(self,unioninfo): # 集合的交集
return self.gather & unioninfo
def get_union(self,unioninfo): # 集合的并集
return self.gather | unioninfo
def del_difference(self,unioninfo):pass set_info = Setinfo({1,2,3})
print(set_info.get_union({3,4,5}))
执行输出:
{1, 2, 3, 4, 5}
5.完成第四个需求
class Setinfo(object):
def __init__(self,gather):
self.gather = gather
def add_setinfo(self,keyname): # 集合元素添加
self.gather.add(keyname)
return self.gather
def get_intersection(self,unioninfo): # 集合的交集
return self.gather & unioninfo
def get_union(self,unioninfo): # 集合的并集
return self.gather | unioninfo
def del_difference(self,unioninfo): # 集合的差集
return self.gather - unioninfo set_info = Setinfo({1,2,3})
print(set_info.del_difference({3,4,5}))
执行输出:
{1, 2}
明日默写:
from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self):pass # 抽象方法 class Alipay(Payment):
def pay(self,money):
print('使用支付宝支付了%s元'%money) class QQpay(Payment):
def pay(self,money):
print('使用qq支付了%s元'%money) class Wechatpay(Payment):
def pay(self,money):
print('使用微信支付了%s元'%money)
def recharge(self):pass def pay(a,money):
a.pay(money) a = Alipay()
a.pay(100)
pay(a,100)
图表总结:
python 全栈开发,Day21(抽象类,接口类,多态,鸭子类型)的更多相关文章
- python 全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)
昨日内容回顾 线程什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线程是什么关系? 线程是在进程中的 一个执行单位 多进程 本质上开启的这个进程里就有一个线程 多线程 单纯的在当 ...
- python 全栈开发,Day20(object类,继承与派生,super方法,钻石继承)
先来讲一个例子 老师有生日,怎么组合呢? class Birthday: # 生日 def __init__(self,year,month,day): self.year = year self.m ...
- python全栈开发day21面向对象初识总结
- Python全栈开发【面向对象】
Python全栈开发[面向对象] 本节内容: 三大编程范式 面向对象设计与面向对象编程 类和对象 静态属性.类方法.静态方法 类组合 继承 多态 封装 三大编程范式 三大编程范式: 1.面向过程编程 ...
- python 全栈开发之路 day1
python 全栈开发之路 day1 本节内容 计算机发展介绍 计算机硬件组成 计算机基本原理 计算机 计算机(computer)俗称电脑,是一种用于高速计算的电子计算机器,可以进行数值计算,又可 ...
- python全栈开发中级班全程笔记(第二模块、第四章)(常用模块导入)
python全栈开发笔记第二模块 第四章 :常用模块(第二部分) 一.os 模块的 详解 1.os.getcwd() :得到当前工作目录,即当前python解释器所在目录路径 impor ...
- python 全栈开发,Day99(作业讲解,DRF版本,DRF分页,DRF序列化进阶)
昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确. - API (IOS,安卓,PC,微信小程序...) - vue.js等框架编写前端时,会比之前写jQuery ...
- 学习笔记之Python全栈开发/人工智能公开课_腾讯课堂
Python全栈开发/人工智能公开课_腾讯课堂 https://ke.qq.com/course/190378 https://github.com/haoran119/ke.qq.com.pytho ...
- Python全栈开发【面向对象进阶】
Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...
随机推荐
- 用Shell编写的俄罗斯方块代码
用Shell编写的俄罗斯方块代码 不得不承认任何一门语言玩6了,啥都能搞出来啊,竟然用Shell编写出来了一个俄罗斯方块游戏的代码,很有意思,这个代码不是我写出来的,不过大家可以下载一下在window ...
- Linux命令之touch
touch命令 用处:新建文件 (默认是文本,你可以自己加后缀) 用法:在终端中输入touch加上要新建的文件的名字(注意!同一目录下文件夹和文件是不允许同名的) 示例: (新建一个名字叫newfil ...
- python---ORM之SQLAlchemy(1)
定义一个类,ORM(对象关系映射)将这个类转换为sql语句,使用pymysql进行执行 一,底层处理 使用engine/connectionpooling/dialect进行数据库操作,engine使 ...
- 《Maven实战》笔记
maven是什么 maven是 构建工具 依赖关系工具 项目信息管理工具 而JAVA世界的ant只是一个构建工具,不具备依赖管理的功能,需要配合使用ivy进行依赖管理. maven的安装 下载mave ...
- 01-VS充当IIS的配置步骤
一. 背景 在实际开发中,经常会遇到需要在线调试,比如:第三方支付的回调.App接口借助PostMan工具测试,需要在代码上直接加断点,来进行调试,VS默认是不支持这种方式,需要手动配置一下,才能达到 ...
- 使用Eclipse Memory Analyzer 进行JAVA内存泄露分析
一,安装 Eclipse Memory Analyzer 在Memory Analyzer的官网找到 update site的地址:
- VMware虚拟机Mac OS X无法调整扩展硬盘大小的解决方案(转)
使用VMware虚拟机搭建的MacOSX,在10.10以上可能会出现无法扩充磁盘大小的问题. 因为很多朋友在初次安装MacOSX的时候都默认选择40G的磁盘大小,结果用了没两天之后就发现磁盘不够用了. ...
- 5. SprigBoot自动配置原理
配置文件到底能写什么?怎么写? 都可以在SpringBoot的官方文档中找到: 配置文件能配置的属性参照 1.自动配置原理: 1).SpringBoot启动的时候加载主配置类,开启了自动配置功 ...
- pygame将文字保存为图片形式
近期自学了点小基础,分享一下用pygame制作字体图片的方法: # 将文字保存为图片形式 import pygame import sys pygame.init() 导入字体包,也可以调用系 ...
- cdn.dns,cms
CDN CDN的全称是Content Delivery Network,即内容分发网络.其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快.更稳定.通过在网络各 ...