From some book, it says when we define a class and implement all abstract methods, even if the class is not inherited from abstract class, the isinstance() check will return True. I try it on my local:
from collections import abc
class Test:
def __len__(self):
return 0
print(isinstance(Test(), abc.Sized))
Because there is only one abstract method in abc.Sized class:_len_, the output is True as expected.
But when I try to define my own abstract class, it fails:
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))
The output is False. I need to register it if I want it to be True:
MyAbstractClass.register(Test)
Why? Why I check it with abs.Sized I don't need to register it but with my own defined abstract class, I have to register it?
There is a way of getting Python to do the duck typing that you are looking for: anything that implements get_size
is automatically an instance of your abstract class.
Many of pythons abstract base classes use this.
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