日期:2020年3月14日
作者:Commas
注释:学习就是为了忘记,什么是接口类,怎么将方法变为属性;
如果您想了解更多有关Python的知识,那么请点《我的Python浅谈系列目录》
一、接口类的定义与作用
接口类
实际上就是一个规范子类的类,只不过这个类与别的类不太一样,接口(内部的方法)本身不实现,子类
继承接口类,子类需要实现接口的功能,否则无法正常工作。那么作用也毋庸置疑,就是规范好子类的接口。
定义一个接口类,我们需要abc模块
(抽象类基类,Abstract Base Classes)中的两个工具abstractmethod, ABCMeta,详情如下:
工具 | 说明 |
---|---|
abstractmethod | 抽象类的装饰器,接口类中的接口需要使用此装饰器 |
ABCMeta | 抽象类元类 |
from abc import abstractmethod, ABCMeta
def 接口类名(metaclass=ABCMeta):
"""定义您的接口类"""
@abstractmethod
def 方法1(self):
"""定义接口名,但不需要实现其功能,由继承此类的子类实现"""
pass
@abstractmethod
def 方法2(self):
"""定义接口名,但不需要实现其功能,由继承此类的子类实现"""
pass
二、图形的接口类示例
接下来我们来定义一个图形的接口类GraphicRule
,提供两个接口,如下:
接口 | 说明 |
---|---|
area | 图形的面积 |
perimeter | 图形的周长 |
接口类仅提供接口名的约束,不实现其接口功能,由其子类的矩形类Rectangle
实现,如果子类Rectangle不实现接口类GraphicRule中所有的接口,即area和perimeter,在实例对象的时候,会抛出异常,如我们不实现接口perimeter,将会得到以下异常:
TypeError: Can't instantiate abstract class Rectangle with abstract methods perimeter
在我们看到这个异常的时候,我们就知道我们还有什么接口没有实现,异常的解决还不是so easy的事情,完整的示例代码如下:
from abc import abstractmethod, ABCMeta
class GraphicRule(metaclass=ABCMeta):
"""图形接口类"""
@abstractmethod
def area(self):
"""面积"""
pass
@abstractmethod
def perimeter(self):
"""周长"""
pass
class Rectangle(GraphicRule):
"""矩形类"""
def __init__(self, b, h):
self.b = b
self.h = h
def area(self):
return self.b*self.h
def perimeter(self):
return (self.b+self.h)*2
# 实例矩形类的一个对象
rect1 = Rectangle(3, 7)
print("矩形面积:{}".format(rect1.area()))
print("矩形周长:{}".format(rect1.perimeter()))
# =======控制台输出结果=======
矩形面积:21
矩形周长:20
三、@property让方法秒变“属性”
上面我们已经完成了一个接口类的定义以及使用接口类,但是看着那两个接口的调用,还是感觉有点别扭。面积area与周长perimeter,在我们的认知中,应该属于一个对象的属性才对;而获得面积get_area与获得周长get_perimeter,看上起更像一个对象的方法。那么我们有没有可能将方法转为属性呢?答案是有的,使用@property装饰器,让方法秒变属性,如下:
@property
def 方法名(self):
pass
所以示例可修改为:
from abc import abstractmethod, ABCMeta
class GraphicRule(metaclass=ABCMeta):
"""图形接口类"""
@abstractmethod
def area(self):
"""面积"""
pass
@abstractmethod
def perimeter(self):
"""周长"""
pass
class Rectangle(GraphicRule):
"""矩形类"""
def __init__(self, b, h):
self.b = b
self.h = h
@property
def area(self):
return self.b*self.h
@property
def perimeter(self):
return (self.b+self.h)*2
rect1 = Rectangle(3, 7)
# (1)注释以下的方法调用
# print("矩形面积:{}".format(rect1.area()))
# print("矩形周长:{}".format(rect1.perimeter()))
# (2)属性调用
print("矩形面积:{}".format(rect1.area))
print("矩形周长:{}".format(rect1.perimeter))
# =======控制台输出结果=======
矩形面积:21
矩形周长:20
版权声明:本文为博主原创文章,如需转载,请给出:
原文链接:https://blog.csdn.net/qq_35844043/article/details/104862886