首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >自定义鸭子类型的Python类型注释

自定义鸭子类型的Python类型注释
EN

Stack Overflow用户
提问于 2016-11-07 21:01:53
回答 2查看 2.4K关注 0票数 9

Python的typing模块定义了许多鸭子类型,例如,typing.SupportsAbs来表示实现__abs__特殊方法的任何类型。

是否有可能以这样的方式定义自定义鸭子类型,以便我可以将它们用作有效的类型注释?

例如,我希望能够注释一个参数应该是一个鸭子类型的等价的threading.Lock,即实现acquirerelease方法的任何对象。理想情况下,我可以将这样的论点注释为SupportsAcquireAndRequireDuckLock,而不是object

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-07 21:30:07

您可以定义一个抽象基类(ABC)来指定接口:

代码语言:javascript
运行
复制
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

这基本上就是协议(如typing.SupportsAbs)的实现方式,尽管没有直接使用ABCMeta

通过给ABC一个方法,您可以在isinstance()issubclass()测试中使用它,这对于mypy这样的工具来说已经足够了。

代码语言:javascript
运行
复制
>>> from threading import Lock
>>> isinstance(Lock(), SupportsAcquireAndRequire)
True
票数 10
EN

Stack Overflow用户

发布于 2020-04-16 18:01:54

typing已经更新以支持像这样的用例,您可以为此使用typing.Protocol

代码语言:javascript
运行
复制
from typing import Protocol, runtime_checkable

@runtime_checkable
class LockLike(Protocol):
    def acquire(self) -> None:
        ...

    def release(self) -> None:
        ...

如果您希望能够像Martijn的答案那样使用isinstance,则需要使用isinstance

代码语言:javascript
运行
复制
>>> from threading import Lock
>>> isinstance(Lock(), RuntimeCheckable)
True
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40474537

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档