joe
joe

Reputation: 9474

Difference between defining typing.Dict and dict?

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?

Upvotes: 309

Views: 293033

Answers (5)

Mohammad Talaei
Mohammad Talaei

Reputation: 402

For people using the new versions of Python: As of Python 3.9, you can specify the types of the keys and values using dict directly, thanks to PEP 585. This means that you don't have to use typing.Dict anymore; you can use dict instead.

# Using typing.Dict (before Python 3.9)
from typing import Dict

new_bandwidths: Dict[str, int] = {"one": 1, "two": 2}

# Using builtins.dict (Python 3.9+)
new_bandwidths: dict[str, int] = {"one": 1, "two": 2}

Upvotes: 7

snowskeleton
snowskeleton

Reputation: 805

If you're coming from google for TypeError: Too few parameters for typing.Dict; actual 1, expected 2, you need to provide a type for both the key and value.

So, Dict[str, str] instead of Dict[str]

Upvotes: 9

Ehsan
Ehsan

Reputation: 4291

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.

Upvotes: 18

Martijn Pieters
Martijn Pieters

Reputation: 1121734

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.

Upvotes: 374

AKS
AKS

Reputation: 19811

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]

Upvotes: 41

Related Questions