我有一个从^{abstractmethod
我想检查一下它是否是一个抽象类,我现在很难办
Determine if a Python class is an Abstract Base Class or Concrete使用inspect.isabstract
进行处方。但是,这仅在使用了abstractmethod
时有效
如何检测类是否直接从ABC
继承,而不使用inspect.isabstract
测试用例
# I need this to be flagged as abstract
class AbstractBaseClassNoAbsMethod(ABC):
pass
# This is currently flaggable with `inspect.isabstract`
class AbstractBaseClassWithAbsMethod(ABC):
@abstractmethod
def some_method(self):
"""Abstract method."""
# I need this to be flagged as not abstract
class ChildClassFromNoAbsMethod(AbstractBaseClassNoAbsMethod):
pass
我考虑过使用issubclass(some_class, ABC)
,但这是True
,即使对于上面的ChildClassFromNoAbsMethod
当前最佳解决方案
我目前最好的解决方案是使用__bases__
。这基本上只是列出父类,请参见How to get the parents of a Python class?
def my_isabstract(obj) -> bool:
"""Get if ABC is in the object's __bases__ attribute."""
try:
return ABC in obj.__bases__
except AttributeError:
return False
这是一个可行的解决办法。我不确定是否有更好/更标准的方法
AbstractBaseClassNoAbsMethod
不是抽象的。从ABC
继承不会使类抽象inspect.isabstract
正在产生正确的结果。您还将看到,如果尝试实例化AbstractBaseClassNoAbsMethod
,而尝试实例化实际抽象类时会引发异常,则不会发生错误如果您想测试一个类是否直接从
abc.ABC
继承,您可以使用__bases__
执行您已经在执行的操作,但是许多抽象类不会从abc.ABC
继承。例如,这是一个抽象类:在这个例子中
B
也是如此:但是
Abstract
和B
都不是直接从abc.ABC
继承的事实上,即使使用ABCMeta作为元类,如果没有abstractmethods(或属性或属性),在Python中,类的所有用途都是而不是抽象的,因为它可以正常实例化
这就是为什么
inspect.isabstract
会返回False如果您确实需要此检查,那么请检查类
__bases__
属性ABC
是一条路要走即使如此,如果直接使用元类
ABCMeta
,该检查也会失败:现在,如果我们编写一些代码,将上面的
MyClass
标记为“抽象”,并将从它派生的另一个标记为“非抽象”,正如您在示例ChildClassFromNoAbsMethod
中所希望的那样,那么从ABC派生的任何类都同样是“用ABCMeta元类声明的类的子类”尽管如此,还是可以检查一个类在其元类层次结构中是否有
ABCMeta
,并一直检查它的祖先,以“查看”它是否是第一个使用ABCMeta作为其层次结构中元类的类,或abc.ABC
的直接子类。但正如你可能已经注意到的,它没有什么用处您最好在
yourAbstractBaseClassNoAbsMethod
中有一个必须重写的一次性标记抽象属性,然后inspect.iabstract
和防止实例化的语言机制都可以工作:相关问题 更多 >
编程相关推荐