Reputation: 2381
I would like to get the keys from an unbound TypedDict
subclass.
What is the correct way to do so?
Below I have a hacky method, and I'm wondering if there's a more standard way.
Current Method
I used inspect.getmembers
on the TypedDict
subclass, and saw the __annotations__
attribute houses a mapping of the keys + type annotations. From there, I use .keys()
to get access to all of the keys.
from typing_extensions import TypedDict
class SomeTypedDict(TypedDict):
key1: str
key2: int
print(SomeTypedDict.__annotations__.keys())
Prints: dict_keys(['key1', 'key2'])
This does work, but I am wondering, is there a better/more standard way?
Versions
python==3.6.5
typing-extensions==3.7.4.2
Upvotes: 16
Views: 11228
Reputation: 11467
For Python 3.10 and newer, it's best to use inspect.get_annotations
. See Annotations Best Practices:
Python 3.10 adds a new function to the standard library:
inspect.get_annotations()
. In Python versions 3.10 and newer, calling this function is the best practice for accessing the annotations dict of any object that supports annotations. This function can also “un-stringize” stringized annotations for you.
The document also discusses how to support earlier versions of Python.
Upvotes: 2
Reputation: 51
You can use get_type_hints
function.
from typing import TypedDict, get_type_hints
class StackParams(TypedDict):
UnsignedAuthorizerName: str
UnsignedAuthorizerStatus: bool
TableName: str
SignedAuthorizerName: str
SignedAuthorizerStatus: bool
SignedAuthorizerTokenKeyName: str
get_type_hints(StackParams)
# {'UnsignedAuthorizerName': str, 'UnsignedAuthorizerStatus': bool, 'TableName': str, 'SignedAuthorizerName': str, 'SignedAuthorizerStatus': bool, 'SignedAuthorizerTokenKeyName': str}
Upvotes: 5
Reputation: 1825
You can also declare a static method like this:
from typing import TypedDict
class StockPrice(TypedDict):
symbol: str
year: int
month: int
day: int
o: int
h: int
l: int
c: int
v: int | None
@staticmethod# type: ignore
def keys():
return StockPrice.__dict__['__annotations__'].keys()
StockPrice.keys()
#dict_keys(['symbol', 'year', 'month', 'day', 'o', 'h', 'l', 'c', 'v'])
Upvotes: 1
Reputation: 2055
The code documentation explicitly states (referring to a sample derived class Point2D
):
The type info can be accessed via the
Point2D.__annotations__
dict, and thePoint2D.__required_keys__
andPoint2D.__optional_keys__
frozensets.
So if the modules code says this, there is no reason to look for another method.
Note that your method only printed the names of the dictionary keys. You can get the names and the type simply by accessing the full dictionary:
print(SomeTypedDict.__annotations__)
Which will get you back all the info:
{'key1': <class 'str'>, 'key2': <class 'int'>}
Upvotes: 21