问题描述
似乎只有当两个 inspect.isabstract
AND Metaclass
都存在时,@abstractmethod
才会返回 true。但这不是医生所说的,至少在我读到它的时候——更重要的是,我根本不相信它是最不令人惊讶的。我需要这个正确/错误吗?
这个类的评估结果与预期的一样抽象
class Both(ABC):
isabstract_result = True
@abstractmethod
def foo(self):
pass
isabstract()
的结果在这里
既不符合文档也不符合常见用法
https://docs.python.org/3/library/abc.html
class JustABC(ABC):
# docs: "an abstract base class can be created by simply deriving from ABC"
isabstract_result = False
我认为这里的技术论点是,为了使派生类变得具体,它们需要实现一个(以前是 abstractmethod
)方法;因此,通过归纳,在其 mro
中没有这种方法的基类不能是 abstract
- 但恕我直言,这将是一个文档错误修复需要,因为它似乎并不是最不令人惊讶的,尤其是考虑到明确的措辞就像今天一样。
这是显示上述内容的可运行代码(以及上述内容的其他一些结果)。在 pythong 3.8.5(默认为 ubuntu 20.04)上运行时,unittest.Testcase
通过
from unittest import TestCase
from abc import abstractmethod,ABC
from inspect import isabstract
# these classes evaluate as abstract as expected
class Both(ABC):
isabstract_result = True
@abstractmethod
def foo(self):
pass
# the result of isabstract() here
# is consistent with neither the docs nor common usage
# https://docs.python.org/3/library/abc.html
class JustABC(ABC):
# docs: "an abstract base class can be created by simply deriving from ABC"
isabstract_result = False
# that this code loads without error would seem to be inconsistent with the docs
# although admittedly nothing about "required" implies there is any error checking
class JustABm:
isabstract_result = False
# docs: Using this decorator requires that the class [...] or is derived from [ABC]"
@abstractmethod
def foo(self):
pass
# for reference,trivial derrived classes preserve the above
class ChildBoth(Both):
isabstract_result = True
class ChildJustABm(JustABC):
isabstract_result = False
class ChildJustABC(JustABm,ABC):
isabstract_result = False
# and there is asymitry about adding the other abc notion;
# although this probably makes sense given the implementation & inheritance
class ChildAddABm(JustABC):
isabstract_result = True
@abstractmethod
def foo(self):
pass
class ChildAddABC(JustABm,ABC):
isabstract_result = False
CLASSES = (
JustABC,JustABm,Both,ChildJustABC,ChildJustABm,ChildBoth,ChildAddABm,ChildAddABC,)
class test_isabstract(TestCase):
""" verify the flags above: test passes """
def test_isabstract(self):
for cls,status in zip(CLASSES,map(isabstract,CLASSES)):
self.assertEqual(
cls.isabstract_result,status,f"error,{cls.__name__ = } {'IS' if status else 'is NOT'} abs,which is not expected.",)
def test_runtime_matches_isabstract(self):
# at least the actual runtime behavior is consistent with inspect.isabstract
for cls in CLASSES:
try:
cls()
self.assertFalse(
cls.isabstract_result,f"{cls} instantiated,but should have Failed as ABC",)
except TypeError as _ex:
self.assertTrue(
cls.isabstract_result,f"{cls} Failed to instantiate as abc unexpectedly",)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)