繁体   English   中英

支持__getitem__的类的Python类型提示

[英]Python type hint for classes that support __getitem__

我想将类型提示添加到一个函数,该函数将接受具有__getitem__方法的任何对象。 例如,在

def my_function(hasitems, locator):
    hasitems[locator]

我不想将hasitems限制为像listdict这样的特定类型。 只要它支持__getitem__ ,它就是my_function的合适参数。 如何在不受不必要限制的情况下对其类型进行注释?

编辑:显然PyCharm可以在许多常见案例中推断出适当的提示,但不是在我的实际用例中。 我不能发布代码,因为它是为了工作,我无法找到PyCharm失败的非专有的最小例子。 在任何情况下,原始问题都没有引用PyCharm,它仍然是类型提示的有效用例。

这适用于dict和list,但不适用于任何泛型类型:

from typing import Any, Mapping, Sequence, Union

def my_function(hasitems: Union[Mapping, Sequence], locator: Any) -> Any:
    return hasitems[locator]

如果您愿意安装一个非常官方的扩展名来typing输入扩展名 ,您可以使用一个Protocol ,它应该是PEP-0544的一个实现:

from typing_extensions import Protocol
from typing import Any

class GetItem(Protocol):
    def __getitem__(self: 'Getitem', key: Any) -> Any: pass

class BadGetItem:
    def __getitem__(self, a: int, b: int) -> Any: pass

def do_thing(arg: GetItem):
    pass

do_thing(dict())  # OK
do_thing(BadGetItem())  # Fails with explanation of correct signature
do_thing(1)  # Fails

听起来你基本上想要定义自己的抽象基类(abc)

按照上面的文档,您可以定义一个仅指示__getitem__存在的自定义abc,但让我们使用预定义的abc作为示例。 Mapping abc由__getitem__和其他一些魔术方法组成。 您可以在isinstance使用abcs,但您也可以直接将它们用作类型注释:

def foo(bar: Mapping):
    pass

或者,使用ABCs扩展类型提示支持甚至可以说是你在其他答案中已经看到过的东西:

def foo(bar: Mapping[Any, Any]):
    pass

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM