自从引入协议类以来,抽象基类是否多余?

Are abstract base classes redundant since Protocol classes were introduced?

提问人:NotAName 提问时间:8/5/2022 最后编辑:tadmanNotAName 更新时间:8/4/2023 访问量:632

问:

我正在学习如何使用 Python 3.8 (PEP 544) 中引入的协议类。

因此,类是 from 的子类,它们就像抽象类一样被处理,并具有允许使用结构子类型的额外好处。我试图思考我现在将使用什么抽象基类,我正在画一个空白。typing.ProtocolABCMeta

与 ABC(如果有)相比,协议类的缺点是什么?也许它们会带来性能打击?是否有任何特定情况表明 ABC 仍然是最佳选择?

python 鸭子类型

评论

3赞 juanpa.arrivillaga 8/5/2022
好吧,对于初学者来说,协议不像类那样在运行时强制执行abc
0赞 NotAName 8/5/2022
@juanpa.arrivillaga,您能解释一下在运行时强制执行是什么意思吗?这与协议相比如何?因为就我而言,如果我有一个带有一个协议的协议,并且我有一个显式继承自协议的子类,那么它将在运行时类似地强制执行,不是吗?abcabstractmethod

答:

3赞 joel 8/4/2023 #1

我更喜欢 s,因为它们是明确的。如果有人阅读代码,可能不知道您的类旨在实现另一个模块中的接口或依赖项的深处。同样,您可能会意外地符合 的签名,而不遵守其契约。例如,如果一个函数接受ABCProtocolProtocol

class Image(Protocol):
    def draw() -> None:
        ...

这显然没有意义

class Cowboy:
    def draw() -> None:
         ...

但是类型检查器会很乐意接受它。

评论

0赞 BrianO 10/31/2023
简洁的例子!:)
1赞 joel 10/31/2023
@BrianO谢谢,但实际上不是我的。我不记得我在哪里见过它