简体   繁体   中英

How do I override __getitem__ in a TypedDict?

I'm trying to make a TypedDict subclass that returns None if a key would cause a KeyError and that key is a part of the TypedDict 's annotations as Optional . I realize this isn't quite possible, since TypedDict can't be subclassed except to define annotations. Is there any other eloquent way to do this?

Here's what I'm trying to do:

from typing import TypedDict, get_args, get_origin

class FilledTypedDict(TypedDict):
    def __getitem__(self, k):
        if k in self.__annotations__:
            annotation = self.__annotations__[k]
            if get_origin(annotation) is Union and type(None) in get_args(annotation):
                return None
        return super().__getitem__(k)

This gives me a TypedDict classes can contain only type annotations . How do I work my way around that?

You do not. TypedDict is not a proper type, it is a representation of a regular dict with well-defined items.

The entire point is that there are no instances of TypedDict and any dict with correct items can be assigned to a TypedDict variable.

from typing import TypedDict

class TD(TypedDict):
    a: int
    b: str

print(type(TD(a=1, b="two")))  # <class 'dict'>

td: TD = {"a": 1, "b": "two"}  # valid

This makes it impossible to add behaviour to a TypedDict , since it must always match the dict behaviour exactly.

PEP 589 –– TypedDict - Methods are not allowed, since the runtime type of a TypedDict object will always be just dict (it is never a subclass of dict ).


What can be done is to satisfy the " TypedDict with Optional values" type – by explicitly setting missing values to None .

from typing import Optional, TypedDict

class Call(TypedDict):
    who: str
    when: Optional[str]

call: Call
call = Call(who="Gwen", when="tomorrow")  # valid
call = {"who": "me", "when": None}        # valid
call = {"who": "us"}                      # error: Missing key 'when' for TypedDict "Call"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM