Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python确定类是否是抽象的(ABC),而不使用abstractmethod_Python_Oop_Abc_Abstract Methods - Fatal编程技术网

Python确定类是否是抽象的(ABC),而不使用abstractmethod

Python确定类是否是抽象的(ABC),而不使用abstractmethod,python,oop,abc,abstract-methods,Python,Oop,Abc,Abstract Methods,我有一个继承自的类,但没有任何抽象方法 我想检查一下它是否是一个抽象类,我现在很难办 规定使用inspect.isastract。但是,这仅在使用了抽象方法时有效 如何检测类是否直接从ABC继承,而不使用inspect.isastract 测试用例 #我需要将此标记为抽象 类AbstractBaseClassNoAbsMethod(ABC): 通过 #当前可使用'inspect.isabstract'标记此项` 类AbstractBaseClassWithAbsMethod(ABC): @抽象

我有一个继承自的类,但没有任何
抽象方法

我想检查一下它是否是一个抽象类,我现在很难办

规定使用
inspect.isastract
。但是,这仅在使用了
抽象方法
时有效

如何检测类是否直接从
ABC
继承,而不使用
inspect.isastract


测试用例

#我需要将此标记为抽象
类AbstractBaseClassNoAbsMethod(ABC):
通过
#当前可使用'inspect.isabstract'标记此项`
类AbstractBaseClassWithAbsMethod(ABC):
@抽象方法
定义某些_方法(自身):
“”“抽象方法。”“”
#我需要将此标记为非抽象
类ChildClassFromNoAbsMethod(AbstractBaseClassNoAbsMethod):
通过
我考虑过使用
issubclass(some_class,ABC)
,但这是
正确的
,即使对于上面的
childclassfromnobs方法


当前最佳解决方案

我目前最好的解决方案是使用
\uuuuuuuuuuuuu
。这基本上只是列出父类,请参见

def my_isastract(obj)->bool:
“”“如果ABC在对象的“基”属性中,则获取。”“”
尝试:
返回目标库中的ABC__
除属性错误外:
返回错误

这是一个可行的解决办法。我不确定是否有更好/更标准的方法。AbstractBaseClassNoAbsMethod不是抽象的。从
ABC
继承不会使类抽象<代码>检查。IsaStract正在生成正确的结果。您还将看到,如果尝试实例化
AbstractBaseClassNoAbsMethod
,而尝试实例化实际抽象类时引发异常,则不会发生错误

如果您想测试一个类是否直接从
abc.abc
继承,您可以使用
\uuuu基
执行您已经在做的操作,但是许多抽象类不会从
abc.abc
继承。例如,这是一个抽象类:

class Abstract(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def foo(self):
        pass
在本例中,
B
也是如此:

class A(abc.ABC):
    @abc.abstractmethod
    def foo(self):
        pass

class B(A): pass

但是无论是
Abstract
还是
B
都不是直接从
abc.abc

继承的。事实上,即使使用ABCMeta作为元类,如果没有抽象方法(或属性或属性),在Python中类也不是抽象的,因为它可以正常实例化

这就是为什么
inspect.isastract
将在其上返回False

如果确实需要此检查,请检查
ABC
是一条路要走

即使如此,如果直接使用元类ABCMeta,该检查也会失败:

class MyClass(metaclass=ABCMeta):
   pass
现在,如果我们编写一些代码,将上面的
MyClass
标记为“抽象”,并将从中派生的另一个标记为“非抽象”,正如您的示例
ChildClassFromNoAbsMethod
所示,那么从ABC派生的任何类都同样是“用ABCMeta元类声明的类的子类”

尽管如此,还是可以检查一个类在其元类层次结构中是否有
ABCMeta
,并一直检查它的祖先,以“查看”它是在其层次结构中使用ABCMeta作为元类的第一个类,还是
abc.abc
的直接子类。但正如你可能已经注意到的,它没有什么用处

您最好在
yourAbstractBaseClassNoAbsMethod
中有一个必须重写的一次性标记抽象属性,然后
inspect.iabstract
和防止实例化的语言机制都可以简单地工作:


在[37]中:A类(ABC):
…:marker=abstractmethod(lambda:None)
...:                                                                                                                             
在[38]中:检查isabstract(A)
Out[38]:对
在[39]中:B(A)类:
…:标记=无
...:                                                                                                                             
In[40]:B()
出[40]:
在[41]中:检查isabstract(B)
Out[41]:假

我似乎误解了抽象类Spython对抽象类的实现实际上相当奇特,因为检查只在运行时进行,并且在尝试实例化抽象类时进行。就传统OOP文献而言,Python根本没有“抽象类”。感谢您为答案添加了更多颜色,以及@jsbueno可能的解决方法!