python接口和抽象类的区别_Python中抽象类和接口的区别

Python中的抽象类和接口有什么区别?

对象的接口是该对象上的一组方法和属性 .

在Python中,我们可以使用抽象基类来定义和实施接口 .

使用抽象基类

例如,假设我们要使用 collections 模块中的一个抽象基类:

import collections

class MySet(collections.Set):

pass

如果我们尝试使用它,我们得到 TypeError 因为我们创建的类不支持集合的预期行为:

>>> MySet()

Traceback (most recent call last):

File "", line 1, in

TypeError: Can't instantiate abstract class MySet with abstract methods

__contains__, __iter__, __len__

所以我们要求至少实现 __contains__ , __iter__ 和 __len__ . 让我们使用documentation中的这个实现示例:

class ListBasedSet(collections.Set):

"""Alternate set implementation favoring space over speed

and not requiring the set elements to be hashable.

"""

def __init__(self, iterable):

self.elements = lst = []

for value in iterable:

if value not in lst:

lst.append(value)

def __iter__(self):

return iter(self.elements)

def __contains__(self, value):

return value in self.elements

def __len__(self):

return len(self.elements)

s1 = ListBasedSet('abcdef')

s2 = ListBasedSet('defghi')

overlap = s1 & s2

实现:创建抽象基类

我们可以通过将元类设置为 abc.ABCMeta 并在相关方法上使用 abc.abstractmethod 装饰器来创建我们自己的抽象基类 . 元类将装饰函数添加到 __abstractmethods__ 属性,防止实例化,直到定义它们为止 .

import abc

例如,“effable”被定义为可以用单词表达的东西 . 假设我们想在Python 2中定义一个可行的抽象基类:

class Effable(object):

__metaclass__ = abc.ABCMeta

@abc.abstractmethod

def __str__(self):

raise NotImplementedError('users must define __str__ to use this base class')

或者在Python 3中,元类声明略有变化:

class Effable(object, metaclass=abc.ABCMeta):

@abc.abstractmethod

def __str__(self):

raise NotImplementedError('users must define __str__ to use this base class')

现在,如果我们尝试在不实现接口的情况下创建一个可用的对象:

class MyEffable(Effable):

pass

并尝试实例化它:

>>> MyEffable()

Traceback (most recent call last):

File "", line 1, in

TypeError: Can't instantiate abstract class MyEffable with abstract methods __str__

我们被告知我们还没有完成这项工作 .

现在,如果我们通过提供预期的界面来遵守:

class MyEffable(Effable):

def __str__(self):

return 'expressable!'

然后我们可以使用从抽象类派生的类的具体版本:

>>> me = MyEffable()

>>> print(me)

expressable!

我们还可以做其他事情,例如注册已经实现这些接口的虚拟子类,但我认为这超出了这个问题的范围 . 然而,此处演示的其他方法必须使用 abc 模块来调整此方法 .

结论

我们已经证明,Abstract Base Class的创建定义了Python中自定义对象的接口 .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值