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(抽象类,接口类,多态,鸭子类型)

上一篇:2020年将热门的8大IT职业领域


下一篇:jq的bind用法