Python type annotation for custom duck type

℡╲_俬逩灬. 提交于 2019-12-05 22:34:23

You can define an abstract base class (ABC) to specify the interface:

from abc import ABCMeta, abstractmethod

class SupportsAcquireAndRequire(metaclass=ABCMeta):
    @abstractmethod
    def acquire(self):
        pass

    @abstractmethod
    def release(self):
        pass

    @classmethod
    def __subclasshook__(cls, C):
        for method in ('release', 'acquire'):
            for B in C.__mro__:
                if method in B.__dict__:
                    if B.__dict__[method] is None:
                        return NotImplemented
                    break
            else:
                return NotImplemented
        return True

This is basically how the protocols (like typing.SupportsAbs) are implemented, albeit without directly using ABCMeta.

By giving the ABC a __subclasshook__ method, you can use it in isinstance() and issubclass() tests, which is more than good enough for tools like mypy:

>>> from threading import Lock
>>> isinstance(Lock(), SupportsAcquireAndRequire)
True
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!