Python中的抽象类和接口有什么区别?
一个对象的接口是该对象上的一组方法和属性。
在 Python 中,我们可以使用抽象基类来定义和实施接口。
例如,假设我们想使用collections模块中的抽象基类之一:
collections
import collections class MySet(collections.Set): pass
如果我们尝试使用它,我们会得到一个,TypeError因为我们创建的类不支持集合的预期行为:
TypeError
>>> MySet() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Can't instantiate abstract class MySet with abstract methods __contains__, __iter__, __len__
所以我们至少 需要实现__contains__,__iter__和 __len__。让我们使用文档中的这个实现示例:
__contains__
__iter__
__len__
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__属性中,防止实例化,直到这些被定义。
abc.ABCMeta
abc.abstractmethod
__abstractmethods__
import abc
例如,“可言”被定义为可以用文字表达的东西。假设我们想在 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')
现在,如果我们尝试在不实现接口的情况下创建一个 effable 对象:
class MyEffable(Effable): pass
并尝试实例化它:
>>> MyEffable() Traceback (most recent call last): File "<stdin>", line 1, in <module> 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模块来调整此方法。
abc
我们已经证明了抽象基类的创建定义了 Python 中自定义对象的接口。
原文链接:https://codingdict.com/