Python中抽象类和接口的区别

Python中抽象类和接口的区别,python,interface,abstract-class,Python,Interface,Abstract Class,Python中抽象类和接口的区别是什么?Python实际上没有这两个概念 它使用,这消除了对接口的需要(至少对于计算机:-) PythonPython>=2.6已经完成 抽象基类(缩写) ABCs)通过 提供定义接口的方法 当其他技术,如hasattr()时 那会很笨拙。Python附带 许多用于数据结构的内置ABC (在“收藏”模块中),数字 (在数字模块中)和流 (在io模块中)。您可以创建 您自己的ABC与ABC模块 还有一个模块,它由zope之外的项目使用,比如twisted。我对它不是

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

Python实际上没有这两个概念

它使用,这消除了对接口的需要(至少对于计算机:-)

PythonPython>=2.6已经完成

抽象基类(缩写) ABCs)通过 提供定义接口的方法 当其他技术,如hasattr()时 那会很笨拙。Python附带 许多用于数据结构的内置ABC (在“收藏”模块中),数字 (在数字模块中)和流 (在io模块中)。您可以创建 您自己的ABC与ABC模块

还有一个模块,它由zope之外的项目使用,比如twisted。我对它不是很熟悉,但是有一个wiki页面可能会有所帮助


一般来说,您不需要python中抽象类或接口的概念(已编辑-有关详细信息,请参阅S.Lott的回答)。

有时您会看到以下内容:

class-Abstract1:
“一些描述告诉你它是抽象的,
通常列出您希望提供的方法。”“”
def-aMethod(self):
raise NOTEImplementedError(“应已实施此操作”)
因为Python没有(也不需要)正式的接口契约,所以抽象和接口之间不存在Java风格的区别。如果有人努力定义一个正式的接口,那么它也将是一个抽象类。唯一的区别在于docstring中声明的意图

当你使用duck类型时,抽象和接口之间的区别是令人毛骨悚然的

Java使用接口是因为它没有多重继承

由于Python具有多重继承,您可能还会看到类似的情况

类抽象:
传递很多东西,但遗漏了一些东西
类Mixin1:
定义某物(自我):
通过#一次实施
类Mixin2:
定义某物(自我):
再传一次
类Concrete1(一些抽象,Mixin1):
通过
类Concrete2(一些抽象,Mixin2):
通过

这使用了一种带有mixin的抽象超类来创建不相交的具体子类。

通常,接口仅在使用单一继承类模型的语言中使用。在这些单继承语言中,如果任何类都可以使用特定的方法或方法集,则通常使用接口。同样,在这些单继承语言中,抽象类被用来在不使用或多个方法的情况下定义类变量,或者利用单继承模型来限制可以使用一组方法的类的范围

支持多重继承模型的语言倾向于只使用类或抽象基类,而不使用接口。由于Python支持多重继承,所以它不使用接口,您可能希望使用基类或抽象基类


以更基本的方式解释: 界面有点像一个空的松饼盘。 它是一个类文件,包含一组没有代码的方法定义

抽象类是一样的,但并非所有函数都需要为空。有些可以有代码。它不是完全空的

为什么要区分: Python没有太多实际的区别,但是在大型项目的规划级别上,讨论接口可能更常见,因为没有代码。尤其是当您与熟悉这个术语的Java程序员一起工作时

Python中抽象类和接口的区别是什么? 对象的接口是该对象上的一组方法和属性

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

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

import collections
class MySet(collections.Set):
    pass
如果我们尝试使用它,我们会得到一个
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__
实现:创建抽象基类 我们可以通过将元类设置为
abc.ABCMeta
并在相关方法上使用
abc.abstractmethod
装饰器来创建自己的抽象基类。元类将添加修饰的函数到
\uuuuu abstractmethods\uuuuu
属性,在定义这些函数之前阻止实例化

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')
或者在Python3中,元类声明略有变化:

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
class MyEffable(Effable): 
    def __str__(self):
        return 'expressable!'
并尝试将其实例化:

>>> MyEffable()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class MyEffable with abstract methods __str__
然后,我们可以使用从抽象类派生的类的具体版本:

>>> me = MyEffable()
>>> print(me)
expressable!
我们还可以做其他事情,比如注册已经实现了这些接口的虚拟子类,但我认为这超出了这个问题的范围。但是,此处演示的其他方法必须使用
abc
模块来调整此方法

结论
我们已经演示了抽象基类的创建为Python中的自定义对象定义接口。

抽象类是包含一个或多个抽象方法的类。与抽象方法一起,抽象类可以有静态、类和实例方法。
但在接口的情况下,它将只具有抽象方法,而不具有其他方法。因此,不必继承抽象类,但必须继承接口

为了完整性,我们应该提到 其中引入了ABC并与接口进行了比较, 和原始评论

抽象类不是完美的接口:

class MyEffable(Effable): 
    pass
class MyEffable(Effable): 
    def __str__(self):
        return 'expressable!'
  • 属于继承层次结构
  • The abc.ABCMeta IS "pythonic" interface in python