Python type hint for classes that support __getitem__

前端 未结 3 485
半阙折子戏
半阙折子戏 2020-12-06 16:42

I want to add type hints to a function that will accept any object with a __getitem__ method. For instance, in

def my_function(hasitems, locator         


        
相关标签:
3条回答
  • 2020-12-06 17:26

    This will work for dict and list, but not for any generic type:

    from typing import Any, Mapping, Sequence, Union
    
    def my_function(hasitems: Union[Mapping, Sequence], locator: Any) -> Any:
        return hasitems[locator]
    
    0 讨论(0)
  • 2020-12-06 17:28

    If you're willing to install a not-quite-offical extension to typing, typing-extensions, you can use a Protocol, which should be an implementation of 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
    
    0 讨论(0)
  • 2020-12-06 17:34

    It sounds like you essentially want to define your own abstract base class (abc).

    Following the documentation above, you can define a custom abc that only dictates the presence of __getitem__, but let's use a predefined one for an example. The Mapping abc consists of __getitem__ and a few other magic methods. You can use abcs in isinstance, but you can also directly use them as a type annotations:

    def foo(bar: Mapping):
        pass
    

    Or, using the extended type hinting support of ABCs do even fancies things, which you already saw in other answers:

    def foo(bar: Mapping[Any, Any]):
        pass
    
    0 讨论(0)
提交回复
热议问题