I come from Typescript, new to Python. When I have 2 things to return from a function and I only use these 2 keys for that function return type and nowhere else in the code, I don't create a complete class but I instead use typescript convinient syntax:
fn(): {
'return_key_1': number,
'return_key_2': string,
} {
// statements..
return {
{
'return_key_1': 5,
'return_key_2': 'hello',
'error_key': 9, // IDE shows an error here as I didn't declared this key
}
}
which enables to create rapidly return data structure without the boilerplate of declaring a entire class, and I have all the IDE autocomplete and errors/warning associated to that data-structure.
Is there the same in Python ? I saw there are NamedTuple, or new @dataclass classes from Python 3.7, but how do you make Python return a NamedTuple with defined keys without declaring the class elsewhere but in the return type ?
I tried:
def fn(self) -> NamedTuple('MyTuple', fields = [('params', str), ('cursor_end', int)]):
return {
'params': 'hello',
'cursor_end': 4,
}
But PyCharm says "Expected type 'MyTuple', got 'dict[str, str | int]' instead"
Since your sample function returns a dict, you should type the returning value with typing.TypedDict
instead:
from typing import TypedDict
def f() -> TypedDict('', {
'return_key_1': int,
'return_key_2': str,
}):
return {
'return_key_1': 5,
'return_key_2': 'hello',
'error_key': 9, # PyCharm shows an error here
}
Note, as @juanpa.arrivillaga points out in the comment, that while the above looks clean and conveniently works in PyCharm, it is unfortunately not officially part of the Python type annotation system. You would have to define the TypedDict
in advance instead of inline in order to conform to the official specifications and satisfy tools that strictly adhere to the specs, like the example below, which is almost identical to the code above except in naming the TypedDict
in advance:
from typing import TypedDict
MyDict = TypedDict('MyDict', {
'return_key_1': int,
'return_key_2': str,
})
def f() -> MyDict:
return {
'return_key_1': 'a',
'return_key_2': 'hello',
'error_key': 9,
}
Demo in mypy: https://mypy-play.net/?mypy=latest&python=3.11&gist=4fbb933f9f9441fced1931d7b32d4c7d