Type hints in namedtuple
Question:
Consider following piece of code:
from collections import namedtuple
point = namedtuple("Point", ("x:int", "y:int"))
The Code above is just a way to demonstrate as to what I am trying to achieve.
I would like to make namedtuple
with type hints.
Do you know any elegant way how to achieve result as intended?
Answers:
You can use typing.NamedTuple
From the docs
Typed version of namedtuple
.
>>> import typing
>>> Point = typing.NamedTuple("Point", [('x', int), ('y', int)])
This is present only in Python 3.5 onwards
The prefered Syntax for a typed named tuple since 3.6 is
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int = 1 # Set default value
Point(3) # -> Point(x=3, y=1)
Edit
Starting Python 3.7, consider using dataclasses
(your IDE may not yet support them for static type checking):
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int = 1 # Set default value
Point(3) # -> Point(x=3, y=1)
Just to be fair, NamedTuple
from typing
:
>>> from typing import NamedTuple
>>> class Point(NamedTuple):
... x: int
... y: int = 1 # Set default value
...
>>> Point(3)
Point(x=3, y=1)
equals to classic namedtuple
:
>>> from collections import namedtuple
>>> p = namedtuple('Point', 'x,y', defaults=(1, ))
>>> p.__annotations__ = {'x': int, 'y': int}
>>> p(3)
Point(x=3, y=1)
So, NamedTuple
is just syntax sugar for namedtuple
Below, you can find a creating NamedTuple
function from the source code of python 3.10
. As we can see, it uses collections.namedtuple
constructor and adds __annotations__
from extracted types:
def _make_nmtuple(name, types, module, defaults = ()):
fields = [n for n, t in types]
types = {n: _type_check(t, f"field {n} annotation must be a type")
for n, t in types}
nm_tpl = collections.namedtuple(name, fields,
defaults=defaults, module=module)
nm_tpl.__annotations__ = nm_tpl.__new__.__annotations__ = types
return nm_tpl
Consider following piece of code:
from collections import namedtuple
point = namedtuple("Point", ("x:int", "y:int"))
The Code above is just a way to demonstrate as to what I am trying to achieve.
I would like to make namedtuple
with type hints.
Do you know any elegant way how to achieve result as intended?
You can use typing.NamedTuple
From the docs
Typed version of
namedtuple
.
>>> import typing
>>> Point = typing.NamedTuple("Point", [('x', int), ('y', int)])
This is present only in Python 3.5 onwards
The prefered Syntax for a typed named tuple since 3.6 is
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int = 1 # Set default value
Point(3) # -> Point(x=3, y=1)
Edit
Starting Python 3.7, consider using dataclasses
(your IDE may not yet support them for static type checking):
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int = 1 # Set default value
Point(3) # -> Point(x=3, y=1)
Just to be fair, NamedTuple
from typing
:
>>> from typing import NamedTuple
>>> class Point(NamedTuple):
... x: int
... y: int = 1 # Set default value
...
>>> Point(3)
Point(x=3, y=1)
equals to classic namedtuple
:
>>> from collections import namedtuple
>>> p = namedtuple('Point', 'x,y', defaults=(1, ))
>>> p.__annotations__ = {'x': int, 'y': int}
>>> p(3)
Point(x=3, y=1)
So, NamedTuple
is just syntax sugar for namedtuple
Below, you can find a creating NamedTuple
function from the source code of python 3.10
. As we can see, it uses collections.namedtuple
constructor and adds __annotations__
from extracted types:
def _make_nmtuple(name, types, module, defaults = ()):
fields = [n for n, t in types]
types = {n: _type_check(t, f"field {n} annotation must be a type")
for n, t in types}
nm_tpl = collections.namedtuple(name, fields,
defaults=defaults, module=module)
nm_tpl.__annotations__ = nm_tpl.__new__.__annotations__ = types
return nm_tpl