Time will tell.
1、接口:
一组功能的集合,但是接口中仅包含功能的名字,不包含具体实现代码。
拿生活中的东西举例:USB接口、HDMI、VGA、WLAN网线接口。
接口的本质:一套协议标准,遵循了这个标准的对象就能够被调用(调谁都可以)
接口的目的:提高扩展性。
例如:电脑提前制定一套USB接口协议,只要你的设备遵循该协议,那么它就可以被电脑使用,无论鼠标、键盘还是什么类型。
# 协议:支持打开关闭,读写数据
class USB:
def open(self):
pass
def close(self):
pass
def read(self):
pass
def write(self):
pass
# 按USB标准制作鼠标
class Mouse(USB):
def open(self):
# 打开方法
print("鼠标开机了")
def close(self):
print("鼠标关闭了")
def read(self):
print("获取了光标位置")
def write(self): # 请忽略鼠标配置
print("鼠标可以写入灯光颜色等数据...")
# 至此,Mouse就算是一个合格的USB设备了
# 按USB标准制作键盘
class KeyBoard(USB):
def open(self):
# 打开方法
print("键盘开机了")
def close(self):
print("键盘关闭了")
def read(self):
print("获取了按键字符...")
def write(self): # 请忽略鼠标配置
print("键盘可以写入灯光颜色等数据...")
# 至此,Mouse就算是一个合格的USB设备了
# ..........其他符合USB接口协议的设备...........
def pc(usb_device):
usb_device.open()
usb_device.read()
usb_device.write()
usb_device.close()
mouse = Mouse()
# 将鼠标传给pc
pc(mouse)
# 鼠标开机了
# 获取了光标位置
# 鼠标不支持写入数据
# 鼠标关闭了
key_board = KeyBoard()
pc(key_board)
# 键盘开机了
# 获取了按键字符...
# 键盘可以写入灯光颜色等数据...
# 键盘关闭了
在上述过程中,鼠标键盘的使用都没有改变 pc 的代码使用方式,体现了扩展性和复用性。pc 的代码一旦完成,无论后期什么样的设备,只要遵循了USB接口协议,就都能够被 pc 识别并调用。
接口主要是为了方便对象的使用者,降低使用者的学习难度,只需要学习一套使用方法就能以不变应万变。如果子类没有按照你的协议来设计,你也没办法限制它,这将导致代码无法运行。
2、abc模块(抽象类)
abc 是 abstract class(抽象类) 的缩写。可以限制子类必须实现类中定义的抽象方法,防止一些类不按规定来写。类中没有方法的具体实现代码的类。
代码:
import abc # abc是 abstract class(抽象类) 的缩写,不是随便写的
class AClass(metaclass=abc.ABCMeta): # 抽象类
@abc.abstractmethod # 装饰抽象方法
def run(self):
pass
@abc.abstractmethod # 装饰抽象方法
def run2(self):
pass
class B(AClass):
pass
# b = B() # 直接报错,TypeError: Can't instantiate abstract class B with abstract methods run
class C(AClass):
def run(self):
print("runrunrun....")
# c = C() # 少实现了一个方法,直接报错 TypeError: Can't instantiate abstract class C with abstract methods run2
class D(AClass):
def run(self):
print("runrunrun....")
def run2(self):
print("runrunrun2....")
d = D() # 把抽象类的方法都实现了,不会报错
3、鸭子类型
Python 一般不会限制你必须怎么写,而作为一个优秀的程序员应该自觉遵守相关协议,所以有了鸭子类型一说。
对鸭子类型的解释:
Python 不支持多态,多态的概念是应用在 java 和 C# 这类强类型语言中的,Python 崇尚的是鸭子类型(Duck Typing)。
鸭子类型是一种动态类型的风格。一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。
这个概念名字来源于 James Whitcomb Riley 提出的鸭子测试,“鸭子测试”可以这样表述:
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
在鸭子类型中,关注的不是对象类型本身,而是它是如何使用的。我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫的方法。这样的一个函数可以接受一个任意类型的对象,调用它的走和叫的方法。如果被调用的方法不存在,则会引发一个运行时错误。
通俗地说,如果这个对象长得像鸭子,走路像鸭子,那么它就是鸭子。没必要方方面面都像。拥有相同的属性和方法,那么就可以把它看成是同样的类,可以提高扩展性。
代码:
# 默认按USB标准制作鼠标
class Mouse:
@staticmethod
def open():
# 打开方法
print("鼠标开机了")
@staticmethod
def close():
print("鼠标关闭了")
@staticmethod
def read():
print("获取了光标位置")
@staticmethod
def write(): # 请忽略鼠标配置
print("鼠标可以写入灯光颜色等数据...")
# 默认按USB标准制作键盘
class KeyBoard:
@staticmethod
def open():
# 打开方法
print("键盘开机了")
@staticmethod
def close():
print("键盘关闭了")
@staticmethod
def read():
print("获取了按键字符...")
@staticmethod
def write(): # 请忽略鼠标配置
print("键盘可以写入灯光颜色等数据...")
# ..........其他符合USB接口协议的设备...........
def pc(usb_device):
usb_device.open()
usb_device.read()
usb_device.write()
usb_device.close()
mouse = Mouse()
# 将鼠标传给pc
pc(mouse) # 可以正常使用
# 鼠标开机了
# 获取了光标位置
# 鼠标不支持写入数据
# 鼠标关闭了
key_board = KeyBoard()
pc(key_board) # 可以正常使用
# 键盘开机了
# 获取了按键字符...
# 键盘可以写入灯光颜色等数据...
# 键盘关闭了
上面的案例中依然没有改变 pc 中的代码,而 Mouse、KeyBoard 这样的类也可以直接交给 pc 使用,它们看起来用起来都像是前面写的 USB 接口协议,所以它们就是鸭子类型。
总结
1、接口是一套协议规范,明确子类们应该具备哪些功能。
2、抽象类是用于强制要求子类必须按照协议中的规定来(接口中定义的)实现。
3、Python 不推崇限制语法,我们可以设计成鸭子类型,让多个不同类对象具备相同的属性和方法,对于使用者而言可以以不变应万变,轻松地使用各种符合协议的对象。
好啦,关于 Python 的接口、抽象类的内容就分享到这里了。如果你对Python案例练习题、面试题、自动化测试感兴趣的话,可以加入我们175317069一起学习。群里会有各项资源发放,更有行业深潜多年的测试人技术分析讲解。期待你的加入!
最后祝愿你能成为一名优秀的工程师!
欢迎【评论】、【点赞】、【关注】~
Time will tell.(时间会证明一切)