<p>事实上,即使使用ABCMeta作为元类,如果没有abstractmethods(或属性或属性),在Python中,类的所有用途都是<em>而不是</em>抽象的,因为它可以正常实例化</p>
<p>这就是为什么<code>inspect.isabstract</code>会返回False</p>
<p>如果您确实需要此检查,那么请检查类<code>__bases__</code>属性
<code>ABC</code>是一条路要走</p>
<p>即使如此,如果直接使用元类<code>ABCMeta</code>,该检查也会失败:</p>
<pre><code>class MyClass(metaclass=ABCMeta):
pass
</code></pre>
<p>现在,如果我们编写一些代码,将上面的<code>MyClass</code>标记为“抽象”,并将从它派生的另一个标记为“非抽象”,正如您在示例<code>ChildClassFromNoAbsMethod</code>中所希望的那样,那么从ABC派生的任何类都同样是“用ABCMeta元类声明的类的子类”</p>
<p>尽管如此,还是可以检查一个类在其元类层次结构中是否有<code>ABCMeta</code>,并一直检查它的祖先,以“查看”它是否是第一个使用ABCMeta作为其层次结构中元类的类,<em>或<code>abc.ABC</code>的直接子类。但正如你可能已经注意到的,它没有什么用处</p>
<p>您最好在<code>yourAbstractBaseClassNoAbsMethod</code>中有一个必须重写的一次性标记抽象属性,然后<code>inspect.iabstract</code>和防止实例化的语言机制都可以工作:</p>
<pre class="lang-py prettyprint-override"><code>
In [37]: class A(ABC):
...: marker = abstractmethod(lambda : None)
...:
In [38]: inspect.isabstract(A)
Out[38]: True
In [39]: class B(A):
...: marker = None
...:
In [40]: B()
Out[40]: <__main__.B at 0x7f389bf19cd0>
In [41]: inspect.isabstract(B)
Out[41]: False
</code></pre>