Difference between defining typing.Dict and dict?

PythonDictionaryType HintingPython Typing

Python Problem Overview


I am practicing using type hints in Python 3.5. One of my colleague uses typing.Dict:

import typing


def change_bandwidths(new_bandwidths: typing.Dict,
                      user_id: int,
                      user_name: str) -> bool:
    print(new_bandwidths, user_id, user_name)
    return False


def my_change_bandwidths(new_bandwidths: dict,
                         user_id: int,
                         user_name: str) ->bool:
    print(new_bandwidths, user_id, user_name)
    return True


def main():
    my_id, my_name = 23, "Tiras"
    simple_dict = {"Hello": "Moon"}
    change_bandwidths(simple_dict, my_id, my_name)
    new_dict = {"new": "energy source"}
    my_change_bandwidths(new_dict, my_id, my_name)

if __name__ == "__main__":
    main()

Both of them work just fine, there doesn't appear to be a difference.

I have read the typing module documentation.

Between typing.Dict or dict which one should I use in the program?

Python Solutions


Solution 1 - Python

There is no real difference between using a plain typing.Dict and dict, no.

However, typing.Dict is a Generic type * that lets you specify the type of the keys and values too, making it more flexible:

def change_bandwidths(new_bandwidths: typing.Dict[str, str],
                      user_id: int,
                      user_name: str) -> bool:

As such, it could well be that at some point in your project lifetime you want to define the dictionary argument a little more precisely, at which point expanding typing.Dict to typing.Dict[key_type, value_type] is a 'smaller' change than replacing dict.

You can make this even more generic by using Mapping or MutableMapping types here; since your function doesn't need to alter the mapping, I'd stick with Mapping. A dict is one mapping, but you could create other objects that also satisfy the mapping interface, and your function might well still work with those:

def change_bandwidths(new_bandwidths: typing.Mapping[str, str],
                      user_id: int,
                      user_name: str) -> bool:

Now you are clearly telling other users of this function that your code won't actually alter the new_bandwidths mapping passed in.

Your actual implementation is merely expecting an object that is printable. That may be a test implementation, but as it stands your code would continue to work if you used new_bandwidths: typing.Any, because any object in Python is printable.


*: Note: If you are using Python 3.7 or newer, you can use dict as a generic type if you start your module with from __future__ import annotations, and as of Python 3.9, dict (as well as other standard containers) supports being used as generic type even without that directive.

Solution 2 - Python

typing.Dict is a generic version of dict:

> class typing.Dict(dict, MutableMapping[KT, VT])

> A generic version of dict. The usage of this type is as follows:

> def get_position_in_index(word_list: Dict[str, int], word: str) -> int: return word_list[word]

Here you can specify the type of key and values in the dict: Dict[str, int]

Solution 3 - Python

as said in python org:

> class typing.Dict(dict, MutableMapping[KT, VT])

> A generic version of dict. Useful for annotating return types. To > annotate arguments it is preferred to use an abstract collection type > such as Mapping.

This type can be used as follows:

def count_words(text: str) -> Dict[str, int]:
    ...

But dict is less general and you will be able to alter the mapping passed in. In fact, in python.Dict you specify more details.

Another tip:

> Deprecated since version 3.9: builtins.dict now supports []. See PEP 585 > and Generic Alias Type.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjoeView Question on Stackoverflow
Solution 1 - PythonMartijn PietersView Answer on Stackoverflow
Solution 2 - PythonAKSView Answer on Stackoverflow
Solution 3 - PythonEhsan BarkhordarView Answer on Stackoverflow