<p>我读了<a href="http://masnun.rocks/2017/04/15/interfaces-in-python-protocols-and-abcs/" rel="nofollow noreferrer"><em>Interfaces in Python: Protocols and ABCs</em></a>,它让我有了更好的理解。我们有Python中的duck类型:</p>
<blockquote>
<p>If it talks and walks like a duck, then it is a duck.</p>
</blockquote>
<p>但是,<code>Bird</code>和{<cd2>}都可以<code>fly()</code>。但它们不是一回事。因此,我们需要定义一个接口来区分它们。(Python没有<code>interface</code>关键字,因此我们实际上使用的是抽象类)</p>
<p>我来举个例子:</p>
<p>我们的程序中有<code>Duck</code>和{<cd6>}。它们都实现了<code>fly()</code>方法。现在我们想从机库里选一架飞机,让一些人上飞机,然后飞到另一个城市。显然,我们不能把人放在<code>Duck</code>上,所以我们定义了一个名为<code>Plane</code>的接口(实际上是一个抽象类)。我们让<code>MyPlane</code>子类<code>Plane</code>。在</p>
<p>一切正常。当我们想选择一个平面时,我们检查它是否是<code>Plane</code>的子类。然而,波音公司开发了一个包,它有一个<code>Boeing747Plane</code>。我们买了那架飞机(<code>from boeing-airplanes import Boeing747Plane</code>),但它不是公认的飞机。它确实有一个<code>fly()</code>方法,但它不是从我们的<code>Plane</code>类继承的,所以我们的Python解释器不会将它识别为平面。在</p>
<p>好消息是Python是一种灵活的语言。感谢<code>register</code>的<code>register</code>方法,在我们完成<code>Plane.register(Boeing747Plane)</code>之后,<code>Boeing747Plane</code>现在是{<cd9>}的子类。我们可以使用第三方<code>Boeing747Plane</code>,就像我们自己构建的<code>Plane</code>。万岁!在</p>
<p>所以你看,当我们想把一个来自第三方包的类变成我们自己的抽象类的子类时,就会用到虚拟类。我们希望它实现我们的接口,但是我们不能改变它的代码,所以我们明确地告诉解释器“它实现了我们的接口,请把它当作我们自己类的子类”。我想通常我们不想用它,但当你需要的时候,要谨慎使用。
正如lucacappelletti所说,这是Python遵循其“我们在这里是成年人”的理念所允许的众多灵活性之一。在</p>