Home > Back-end >  How would you type hint Dict in Python with constant form but multiple types?
How would you type hint Dict in Python with constant form but multiple types?

Time:07-27

I want to type hint the return object of some_func function, which is always the same format. Is this correct?

from typing import List, Dict


def some_func() -> List[Dict[str, int, str, List[CustomObject]]]:
    my_list = [
               {"ID": 1, "cargo": [CustomObject(), CustomObject()]},
               {"ID": 2, "cargo": [CustomObject(), CustomObject()]},
               {"ID": 2, "cargo": [CustomObject(), CustomObject()]}
               ]
    return my_list

CodePudding user response:

one way of correctly type hinting would look like this:

from typing import List, Dict, Union

def some_func() -> List[Dict[str, Union[int, List[CustomObject]]]]:
    my_list = [
               {"ID": 1, "cargo": [CustomObject(), CustomObject()]},
               {"ID": 2, "cargo": [CustomObject(), CustomObject()]},
               {"ID": 2, "cargo": [CustomObject(), CustomObject()]}
               ]
    return my_list

for a brief explanation, when type annotating a dict, you can only have two arguments, the first being the type of any given key, and the second, the type of any given value. since keys are always strings, we keep Dict[str, and our keys can be either an integer, or of type CustomObject, to represent different possibilities in type annotations we use Union, and so in the end we get:

Dict[str, Union[int, List[CustomObject]]

for some additional notes, in python 3.9 or above you may replace Dict imported from typing, with the builtin dict, and in python 3.10 or above, unions can be represented as type | type, and you can replace List with the builtin list

for a cleaner result you may want to use a typedDict, the overall result would be:

from typing import TypedDict

class customDict(TypedDict):
    ID: int
    cargo: list[CustomObject]

def some_func() -> list[customDict]:
    my_list = [
               {"ID": 1, "cargo": [CustomObject(), CustomObject()]},
               {"ID": 2, "cargo": [CustomObject(), CustomObject()]},
               {"ID": 2, "cargo": [CustomObject(), CustomObject()]}
               ]
    return my_list

each property of the typed dict represents a key of the dicts in my_list, and the following reprents the type of value related to the key

CodePudding user response:

You can do this with a TypedDict:

class MyDict(TypedDict):
    ID: int
    cargo: list[CustomObject]

def some_func()->list[MyDict]:
    pass

A typed dict, see PEP 589 is a way to specify different types for different keys in a dict.

Also note that since python 3.10 you can just use list[type] instead of typing.List[type]. Works for dicts and tuples too.

  • Related