KZiovas
KZiovas

Reputation: 4709

How to declare typing for a dictionary with multiple but specified value types in Python?

I have a method which create a dictionary with 3 values where the key is always a str but the objects for the values of each key are of a different type for example I would like to declare something like this (obviously this is not correct:

Dict[str,ObjectType1,str,ObjectType2,str,List[ObjectType3]]

Note I don't want to use Union for the three value types because I want to ensure that the returned dictionary has exactly this structure

Upvotes: 0

Views: 487

Answers (3)

KZiovas
KZiovas

Reputation: 4709

Ok this is not doing what I wanted to initially but by the discussion started thanks to the other replies and comments I realized that the dict I was using was not a good structure for what I wanted, since there is no build in support for this strong typing.

So since I wanted to ensure that I always get back an object with tree elements each of which is of a specific type I changed my data structure to a simple tuple :

Tuple[Tuple[str,str,str],Tuple[ObjectType1,ObjectType2,List[ObjectType3]]

this allows me to use the type checking exactly as I wanted. I store the keys in the first tuple, in order, and the values in the second tuple, in order again, and with type checking. Not ideal but it is a workaround.

This could also work:

Tuple[Tuple[str,ObjectType1],Tuple[str,ObjectType2], Tuple[str,List[ObjectType3]]]

Note (named tuple suggested in another response would work if someone wanted to have fixed keys, but I didnt want that in my case)

Upvotes: 0

Kristina Solovyova
Kristina Solovyova

Reputation: 41

I don't think it's possible with typing...
But you may use NamedTuple in this case if you want to keep strict type notation
E.g. something like this:

from typing import NamedTuple


class MyCustomType(NamedTuple):
    type1: ObjectType1
    type2: ObjectType1
    type3: List[ObjectType3]


def func() -> MyCustomType:
    data = {}
    ...
    return MyCustomType(**data)

Upvotes: 1

joshmeranda
joshmeranda

Reputation: 3251

Python was not designed for strong typing like this. The best way is to probably define the values them as a Union:

dict[str, Union[ObjectType1,. ObjectType2, list[ObjectType3]]

When you access them you'll have to check their type:

value = d[key]

if isinstance(value, ObjectType1):
    pass
elif isinstance(value, ObjectType2):
    pass
elif isinstance(value, list):
    pass
else:
    raise TypeError(f"unhandled type: {type(value)}")

Upvotes: 0

Related Questions