从某本书上说,当我们定义一个类并实现所有抽象方法时,即使该类不是从抽象类继承的,isinstance()检查也会返回True。 我在本地试试:
from collections import abc
class Test:
def __len__(self):
return 0
print(isinstance(Test(), abc.Sized))
因为abc.Sized类中只有一个抽象方法:_len_,输出结果为True,符合预期
但是当我尝试定义自己的抽象类时,它失败了:
from abc import abstractmethod, ABCMeta
Class MyAbstractClass(metaclass=ABCMeta):
@abstractmethod
def get_size(self):pass
class Test:
def get_size(self):
return 0
print(isinstance(Test(), MyAbstractClass))
输出为假。如果我希望它是真的,我需要注册它:
MyAbstractClass.register(Test)
为什么?为什么我用 abs.Sized 检查它我不需要注册它但是用我自己定义的抽象类,我必须注册它?
Test
类应该继承MyAbstractClass
.
from abc import abstractmethod, ABCMeta
class MyAbstractClass(metaclass=ABCMeta):
@abstractmethod
def get_size(self):pass
class Test(MyAbstractClass):
def get_size(self):
return 0
print(isinstance(Test(), MyAbstractClass))
有一种方法可以让 Python 执行您正在寻找的鸭子类型:任何实现
get_size
的东西都会自动成为您的抽象类的实例。
许多 python 抽象基类都使用它。
class MyAbstractClass(metaclass=ABCMeta):
@classmethod
def __subclasshook__(cls, C):
if cls is MyAbstractClass:
if any("get_size" in B.__dict__ for B in C.__mro__):
return True
return False