How can a dictionary be subclassed such that the subclass supports generic type hinting? It needs to behave like a dictionary in every way and support type hints of the keys and values. The subclass will add functions that access and manipulate the dictionary data. For example, it will have a valueat(self, idx:int)
function that returns the dictionary value at a given index.
It doesn't require OrderedDict
as its base class, but the dictionary does need to have a predictable order. Since OrderedDict
maintains insertion order and supports type hints, it seems like a reasonable place to start.
Here's what I tried:
from collections import OrderedDict
class ApplicationSpecificDict(OrderedDict[str, int]):
...
However, it fails with the error:
TypeError: 'type' object is not subscriptable
Is this not supported in Python 3.7+, or am I missing something?
By using the setdefault() method, you can add items with new values only for new keys without changing the values for existing keys. This is useful when you don't want to change an existing item. This article describes the following contents.
Python will always remain a dynamically typed language. However, PEP 484 introduced type hints, which make it possible to also do static type checking of Python code. Unlike how types work in most other statically typed languages, type hints by themselves don't cause Python to enforce types.
Here's how you can add type hints to our function: Add a colon and a data type after each function parameter. Add an arrow ( -> ) and a data type after the function to specify the return data type.
Use dict.get() to get the default value for non-existent keys. You can use the get() method of the dictionary ( dict ) to get any default value without an error if the key does not exist.
I posted on this question which yours may be a dupe of, but I will include it here as well because I found both of these questions when I was googling how to do this.
Basically, you need to use the typing Mapping generic
This is the generic annotation that dict uses so you can define other types like MyDict[str, int]
.
How to:
import typing
from collections import OrderedDict
# these are generic type vars to tell mutable-mapping
# to accept any type vars when creating a sub-type of your generic dict
_KT = typing.TypeVar("_KT") # key type
_VT = typing.TypeVar("_VT") # value type
# `typing.MutableMapping` requires you to implement certain functions like __getitem__
# You can get around this by just subclassing OrderedDict first.
# Note: The generic you're subclassing needs to come BEFORE
# the `typing.MutableMapping` subclass or accessing indices won't work.
class ApplicationSpecificDict(
OrderedDict,
typing.MutableMapping[_KT, _VT]
):
"""Your special dict"""
...
# Now define the key, value types for sub-types of your dict
RequestDict = MyDict[str, typing.Tuple[str, str]]
ModelDict = MyDict[str, typing.Any]
Now use you custom types of your sub-typed dict:
from my_project.custom_typing import ApplicationSpecificDict # Import your custom type
def make_request() -> ApplicationSpecificDict:
request = ApplicationSpecificDict()
request["test"] = ("sierra", "117")
return request
print(make_request())
Will output as { "test": ("sierra", "117") }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With