I'm quite new to using type hints in python. I have an app with multiple modules in a package and classes associated to them. I've been trying to find some type hint explanation of how it works when there are multiple scripts and the type defined comes from an object whos script is loaded in another module. Here is a very simplified version for this confusion on the use of type hints.
Given that there is a script for the main app like this:
from modules.FigureFormatter import FigureFormatter
from modules.Plotter import Plotter
class MainApp:
def __init__(self):
formatter = FigureFormatter()
plotter = Plotter()
plotter.plot_figure(formatter.styler['light'])
The modules package contains two modules:
class FigureFormatter:
def __init__(self):
self.styler = {'light': {'prop1': 1,
'prop2': 2},
'dark': {'prop1': 1,
'prop2': 2}}
and
from typing import Dict
class Plotter:
def __inti__(self):
# Some initialization stuff
pass
def plot_figure(self, styler: Dict):
# Plotting figure
pass
What should be the type hint for the styler
argument in plot_figure
method? Essentially it is a dictionary. Obviously it shouldn't be any dictionary, but a dictionary that is an attribute of the FigureFormatting
class instance. Should that module be also imported into Plotter
modules, so the class name could be referenced?
Python 3.8 introduced a TypedDict
hint, which can specify a dictionary with specific str
-valued keys mapped to specific types. For example:
# In modules.FigureFormatter
from typing import TypedDict
StylerProperties = TypedDict('StylerProperties', prop1=int, prop2=int)
StylerType = TypedDict('Styler', light=StylerProperties, dark=StylerProperties)
# In modules.Plotter
from modules.Formatter import StylerType
class Plotter:
...
def plot_figure(self, styler: StylerType):
...
You can also use it TypedDict
as a base class, which the documentation suggests is the intended use. (The called version appears to exist to support versions of Python prior 3.6, which don't allow for variable annotations. Note that TypedDict
was in the experimental typing_extensions
before being promoted to typing
.)
class StylerProperties(TypedDict):
prop1: int
prop2: int
class Styler(TypedDict):
light: StylerProperties
dark: StylerProperties
It doesn't make much sense to further require that the dict comes from a particular class attribute, as being referred to by an attribute doesn't change the dict
value. If being an attribute of FigureFormatter
is important, then just require an instance of FigureFormatter
and extract the dict
yourself:
def plot_figure(self, f: FigureFormatter):
styler = f.styler
...